dcandler updated this revision to Diff 338046.
dcandler added a comment.

I've updated the patch to fix the test failures, and slightly reworked the 
driver code to avoid the above iterator invalidation. I've also added a comment 
there to clarify what it is doing: individually determining whether the sha2 
and aes features should be enabled and explicitly setting them, since they can 
be controlled both by crypto and their specific feature. Using the last 
occurance of either in the vector ensures whatever options are passed to 
-mcpu/-march are evaluated in the correct order.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D99079/new/

https://reviews.llvm.org/D99079

Files:
  clang/include/clang/Basic/arm_neon.td
  clang/lib/Basic/Targets/AArch64.cpp
  clang/lib/Basic/Targets/AArch64.h
  clang/lib/Basic/Targets/ARM.cpp
  clang/lib/Basic/Targets/ARM.h
  clang/lib/Driver/ToolChains/Arch/ARM.cpp
  clang/test/CodeGen/aarch64-neon-range-checks.c
  clang/test/CodeGen/aarch64-neon-sha3.c
  clang/test/CodeGen/aarch64-neon-sm4-sm3.c
  clang/test/CodeGen/arm-target-features.c
  clang/test/CodeGen/arm64_crypto.c
  clang/test/CodeGen/neon-crypto.c
  clang/test/Driver/aarch64-cpus.c
  clang/test/Driver/arm-cortex-cpus.c
  clang/test/Driver/arm-features.c
  clang/test/Driver/arm-mfpu.c
  clang/test/Driver/armv8.1m.main.c
  clang/test/Preprocessor/aarch64-target-features.c
  clang/test/Preprocessor/arm-target-features.c
  llvm/include/llvm/Support/ARMTargetParser.def
  llvm/lib/Support/ARMTargetParser.cpp
  llvm/lib/Target/ARM/ARMInstrNEON.td
  llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
  llvm/test/Bindings/llvm-c/ARM/disassemble.test
  llvm/test/MC/ARM/directive-arch_extension-aes-sha2.s
  llvm/test/MC/ARM/directive-arch_extension-crypto.s
  llvm/test/MC/ARM/neon-crypto.s

Index: llvm/test/MC/ARM/neon-crypto.s
===================================================================
--- llvm/test/MC/ARM/neon-crypto.s
+++ llvm/test/MC/ARM/neon-crypto.s
@@ -9,10 +9,10 @@
 @ CHECK: aese.8 q0, q1          @ encoding: [0x02,0x03,0xb0,0xf3]
 @ CHECK: aesimc.8 q0, q1        @ encoding: [0xc2,0x03,0xb0,0xf3]
 @ CHECK: aesmc.8 q0, q1         @ encoding: [0x82,0x03,0xb0,0xf3]
-@ CHECK-V7: instruction requires: crypto armv8
-@ CHECK-V7: instruction requires: crypto armv8
-@ CHECK-V7: instruction requires: crypto armv8
-@ CHECK-V7: instruction requires: crypto armv8
+@ CHECK-V7: instruction requires: aes armv8
+@ CHECK-V7: instruction requires: aes armv8
+@ CHECK-V7: instruction requires: aes armv8
+@ CHECK-V7: instruction requires: aes armv8
 
 sha1h.32  q0, q1
 sha1su1.32  q0, q1
@@ -20,9 +20,9 @@
 @ CHECK: sha1h.32  q0, q1       @ encoding: [0xc2,0x02,0xb9,0xf3]
 @ CHECK: sha1su1.32 q0, q1      @ encoding: [0x82,0x03,0xba,0xf3]
 @ CHECK: sha256su0.32 q0, q1    @ encoding: [0xc2,0x03,0xba,0xf3]
-@ CHECK-V7: instruction requires: crypto armv8
-@ CHECK-V7: instruction requires: crypto armv8
-@ CHECK-V7: instruction requires: crypto armv8
+@ CHECK-V7: instruction requires: sha2 armv8
+@ CHECK-V7: instruction requires: sha2 armv8
+@ CHECK-V7: instruction requires: sha2 armv8
 
 sha1c.32  q0, q1, q2
 sha1m.32  q0, q1, q2
@@ -38,14 +38,14 @@
 @ CHECK: sha256h.32  q0, q1, q2      @ encoding: [0x44,0x0c,0x02,0xf3]
 @ CHECK: sha256h2.32 q0, q1, q2      @ encoding: [0x44,0x0c,0x12,0xf3]
 @ CHECK: sha256su1.32 q0, q1, q2     @ encoding: [0x44,0x0c,0x22,0xf3]
-@ CHECK-V7: instruction requires: crypto armv8
-@ CHECK-V7: instruction requires: crypto armv8
-@ CHECK-V7: instruction requires: crypto armv8
-@ CHECK-V7: instruction requires: crypto armv8
-@ CHECK-V7: instruction requires: crypto armv8
-@ CHECK-V7: instruction requires: crypto armv8
-@ CHECK-V7: instruction requires: crypto armv8
+@ CHECK-V7: instruction requires: sha2 armv8
+@ CHECK-V7: instruction requires: sha2 armv8
+@ CHECK-V7: instruction requires: sha2 armv8
+@ CHECK-V7: instruction requires: sha2 armv8
+@ CHECK-V7: instruction requires: sha2 armv8
+@ CHECK-V7: instruction requires: sha2 armv8
+@ CHECK-V7: instruction requires: sha2 armv8
 
 vmull.p64 q8, d16, d17
 @ CHECK: vmull.p64  q8, d16, d17    @ encoding: [0xa1,0x0e,0xe0,0xf2]
-@ CHECK-V7: instruction requires: crypto armv8
+@ CHECK-V7: instruction requires: aes armv8
Index: llvm/test/MC/ARM/directive-arch_extension-crypto.s
===================================================================
--- llvm/test/MC/ARM/directive-arch_extension-crypto.s
+++ llvm/test/MC/ARM/directive-arch_extension-crypto.s
@@ -17,38 +17,38 @@
 	.type crypto,%function
 crypto:
 	vmull.p64 q0, d0, d1
-@ CHECK-V7: error: instruction requires: crypto armv8
+@ CHECK-V7: error: instruction requires: aes armv8
 
 	aesd.8 q0, q1
-@ CHECK-V7: error: instruction requires: crypto armv8
+@ CHECK-V7: error: instruction requires: aes armv8
 	aese.8 q0, q1
-@ CHECK-V7: error: instruction requires: crypto armv8
+@ CHECK-V7: error: instruction requires: aes armv8
 	aesimc.8 q0, q1
-@ CHECK-V7: error: instruction requires: crypto armv8
+@ CHECK-V7: error: instruction requires: aes armv8
 	aesmc.8 q0, q1
-@ CHECK-V7: error: instruction requires: crypto armv8
+@ CHECK-V7: error: instruction requires: aes armv8
 
 	sha1h.32 q0, q1
-@ CHECK-V7: error: instruction requires: crypto armv8
+@ CHECK-V7: error: instruction requires: sha2 armv8
 	sha1su1.32 q0, q1
-@ CHECK-V7: error: instruction requires: crypto armv8
+@ CHECK-V7: error: instruction requires: sha2 armv8
 	sha256su0.32 q0, q1
-@ CHECK-V7: error: instruction requires: crypto armv8
+@ CHECK-V7: error: instruction requires: sha2 armv8
 
 	sha1c.32 q0, q1, q2
-@ CHECK-V7: error: instruction requires: crypto armv8
+@ CHECK-V7: error: instruction requires: sha2 armv8
 	sha1m.32 q0, q1, q2
-@ CHECK-V7: error: instruction requires: crypto armv8
+@ CHECK-V7: error: instruction requires: sha2 armv8
 	sha1p.32 q0, q1, q2
-@ CHECK-V7: error: instruction requires: crypto armv8
+@ CHECK-V7: error: instruction requires: sha2 armv8
 	sha1su0.32 q0, q1, q2
-@ CHECK-V7: error: instruction requires: crypto armv8
+@ CHECK-V7: error: instruction requires: sha2 armv8
 	sha256h.32 q0, q1, q2
-@ CHECK-V7: error: instruction requires: crypto armv8
+@ CHECK-V7: error: instruction requires: sha2 armv8
 	sha256h2.32 q0, q1, q2
-@ CHECK-V7: error: instruction requires: crypto armv8
+@ CHECK-V7: error: instruction requires: sha2 armv8
 	sha256su1.32 q0, q1, q2
-@ CHECK-V7: error: instruction requires: crypto armv8
+@ CHECK-V7: error: instruction requires: sha2 armv8
 
 	.arch_extension nocrypto
 @ CHECK-V7: error: architectural extension 'crypto' is not allowed for the current base architecture
@@ -58,51 +58,51 @@
 	.type nocrypto,%function
 nocrypto:
 	vmull.p64 q0, d0, d1
-@ CHECK-V7: error: instruction requires: crypto armv8
-@ CHECK-V8: error: instruction requires: crypto
+@ CHECK-V7: error: instruction requires: aes armv8
+@ CHECK-V8: error: instruction requires: aes
 
 	aesd.8 q0, q1
-@ CHECK-V7: error: instruction requires: crypto armv8
-@ CHECK-V8: error: instruction requires: crypto
+@ CHECK-V7: error: instruction requires: aes armv8
+@ CHECK-V8: error: instruction requires: aes
 	aese.8 q0, q1
-@ CHECK-V7: error: instruction requires: crypto armv8
-@ CHECK-V8: error: instruction requires: crypto
+@ CHECK-V7: error: instruction requires: aes armv8
+@ CHECK-V8: error: instruction requires: aes
 	aesimc.8 q0, q1
-@ CHECK-V7: error: instruction requires: crypto armv8
-@ CHECK-V8: error: instruction requires: crypto
+@ CHECK-V7: error: instruction requires: aes armv8
+@ CHECK-V8: error: instruction requires: aes
 	aesmc.8 q0, q1
-@ CHECK-V7: error: instruction requires: crypto armv8
-@ CHECK-V8: error: instruction requires: crypto
+@ CHECK-V7: error: instruction requires: aes armv8
+@ CHECK-V8: error: instruction requires: aes
 
 	sha1h.32 q0, q1
-@ CHECK-V7: error: instruction requires: crypto armv8
-@ CHECK-V8: error: instruction requires: crypto
+@ CHECK-V7: error: instruction requires: sha2 armv8
+@ CHECK-V8: error: instruction requires: sha2
 	sha1su1.32 q0, q1
-@ CHECK-V7: error: instruction requires: crypto armv8
-@ CHECK-V8: error: instruction requires: crypto
+@ CHECK-V7: error: instruction requires: sha2 armv8
+@ CHECK-V8: error: instruction requires: sha2
 	sha256su0.32 q0, q1
-@ CHECK-V7: error: instruction requires: crypto armv8
-@ CHECK-V8: error: instruction requires: crypto
+@ CHECK-V7: error: instruction requires: sha2 armv8
+@ CHECK-V8: error: instruction requires: sha2
 
 	sha1c.32 q0, q1, q2
-@ CHECK-V7: error: instruction requires: crypto armv8
-@ CHECK-V8: error: instruction requires: crypto
+@ CHECK-V7: error: instruction requires: sha2 armv8
+@ CHECK-V8: error: instruction requires: sha2
 	sha1m.32 q0, q1, q2
-@ CHECK-V7: error: instruction requires: crypto armv8
-@ CHECK-V8: error: instruction requires: crypto
+@ CHECK-V7: error: instruction requires: sha2 armv8
+@ CHECK-V8: error: instruction requires: sha2
 	sha1p.32 q0, q1, q2
-@ CHECK-V7: error: instruction requires: crypto armv8
-@ CHECK-V8: error: instruction requires: crypto
+@ CHECK-V7: error: instruction requires: sha2 armv8
+@ CHECK-V8: error: instruction requires: sha2
 	sha1su0.32 q0, q1, q2
-@ CHECK-V7: error: instruction requires: crypto armv8
-@ CHECK-V8: error: instruction requires: crypto
+@ CHECK-V7: error: instruction requires: sha2 armv8
+@ CHECK-V8: error: instruction requires: sha2
 	sha256h.32 q0, q1, q2
-@ CHECK-V7: error: instruction requires: crypto armv8
-@ CHECK-V8: error: instruction requires: crypto
+@ CHECK-V7: error: instruction requires: sha2 armv8
+@ CHECK-V8: error: instruction requires: sha2
 	sha256h2.32 q0, q1, q2
-@ CHECK-V7: error: instruction requires: crypto armv8
-@ CHECK-V8: error: instruction requires: crypto
+@ CHECK-V7: error: instruction requires: sha2 armv8
+@ CHECK-V8: error: instruction requires: sha2
 	sha256su1.32 q0, q1, q2
-@ CHECK-V7: error: instruction requires: crypto armv8
-@ CHECK-V8: error: instruction requires: crypto
+@ CHECK-V7: error: instruction requires: sha2 armv8
+@ CHECK-V8: error: instruction requires: sha2
 
Index: llvm/test/MC/ARM/directive-arch_extension-aes-sha2.s
===================================================================
--- /dev/null
+++ llvm/test/MC/ARM/directive-arch_extension-aes-sha2.s
@@ -0,0 +1,34 @@
+@ RUN: not llvm-mc -triple armv8-eabi -filetype asm < %s 2> %t  | FileCheck %s
+@ RUN: FileCheck --check-prefix=CHECK-ERROR < %t %s
+@ RUN: not llvm-mc -triple thumbv8-eabi -filetype asm < %s 2> %t | FileCheck %s
+@ RUN: FileCheck --check-prefix=CHECK-ERROR < %t %s
+
+  .syntax unified
+
+  .arch_extension aes
+  .arch_extension sha2
+
+  .type crypto,%function
+crypto:
+  aesd.8 q0, q1
+  sha1c.32 q0, q1, q2
+
+@CHECK-LABEL: crypto:
+@CHECK:	aesd.8 q0, q1
+@CHECK:	sha1c.32 q0, q1, q2
+
+  .arch_extension noaes
+  .arch_extension nosha2
+
+  .type nocrypto,%function
+nocrypto:
+  aesd.8 q0, q1
+  sha1c.32 q0, q1, q2
+
+@CHECK-ERROR: error: instruction requires: aes
+@CHECK-ERROR: aesd.8 q0, q1
+@CHECK-ERROR: ^
+
+@CHECK-ERROR: error: instruction requires: sha2
+@CHECK-ERROR: sha1c.32 q0, q1, q2
+@CHECK-ERROR: ^
Index: llvm/test/Bindings/llvm-c/ARM/disassemble.test
===================================================================
--- llvm/test/Bindings/llvm-c/ARM/disassemble.test
+++ llvm/test/Bindings/llvm-c/ARM/disassemble.test
@@ -1,12 +1,12 @@
 ; RUN: llvm-c-test --disassemble < %s | FileCheck %s
 
-armv8-linux-gnu     +crypto 02 00 81 e0 02 03 b0 f3
-;CHECK: triple: armv8-linux-gnu, features: +crypto
+armv8-linux-gnu     +aes 02 00 81 e0 02 03 b0 f3
+;CHECK: triple: armv8-linux-gnu, features: +aes
 ;CHECK: 02 00 81 e0                  add r0, r1, r2
 ;CHECK: 02 03 b0 f3                  aese.8 q0, q1
 
-armv8-linux-gnu     -crypto 02 00 81 e0 02 03 b0 f3
-;CHECK: triple: armv8-linux-gnu, features: -crypto
+armv8-linux-gnu     -aes 02 00 81 e0 02 03 b0 f3
+;CHECK: triple: armv8-linux-gnu, features: -aes
 ;CHECK: 02 00 81 e0                  add r0, r1, r2
 ;CHECK: 02                           ???
 ;CHECK: 03                           ???
Index: llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
===================================================================
--- llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -500,6 +500,7 @@
                              StringRef FullInst, bool &CanAcceptCarrySet,
                              bool &CanAcceptPredicationCode,
                              bool &CanAcceptVPTPredicationCode);
+  bool enableArchExtFeature(StringRef Name, SMLoc &ExtLoc);
 
   void tryConvertingToTwoOperandForm(StringRef Mnemonic, bool CarrySetting,
                                      OperandVector &Operands);
@@ -12226,9 +12227,7 @@
   }
 }
 
-/// parseDirectiveArchExtension
-///   ::= .arch_extension [no]feature
-bool ARMAsmParser::parseDirectiveArchExtension(SMLoc L) {
+bool ARMAsmParser::enableArchExtFeature(StringRef Name, SMLoc &ExtLoc) {
   // FIXME: This structure should be moved inside ARMTargetParser
   // when we start to table-generate them, and we can use the ARM
   // flags below, that were generated by table-gen.
@@ -12237,46 +12236,43 @@
     const FeatureBitset ArchCheck;
     const FeatureBitset Features;
   } Extensions[] = {
-    { ARM::AEK_CRC, {Feature_HasV8Bit}, {ARM::FeatureCRC} },
-    { ARM::AEK_CRYPTO,  {Feature_HasV8Bit},
-      {ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8} },
-    { ARM::AEK_FP, {Feature_HasV8Bit},
-      {ARM::FeatureVFP2_SP, ARM::FeatureFPARMv8} },
-    { (ARM::AEK_HWDIVTHUMB | ARM::AEK_HWDIVARM),
-      {Feature_HasV7Bit, Feature_IsNotMClassBit},
-      {ARM::FeatureHWDivThumb, ARM::FeatureHWDivARM} },
-    { ARM::AEK_MP, {Feature_HasV7Bit, Feature_IsNotMClassBit},
-      {ARM::FeatureMP} },
-    { ARM::AEK_SIMD, {Feature_HasV8Bit},
-      {ARM::FeatureNEON, ARM::FeatureVFP2_SP, ARM::FeatureFPARMv8} },
-    { ARM::AEK_SEC, {Feature_HasV6KBit}, {ARM::FeatureTrustZone} },
-    // FIXME: Only available in A-class, isel not predicated
-    { ARM::AEK_VIRT, {Feature_HasV7Bit}, {ARM::FeatureVirtualization} },
-    { ARM::AEK_FP16, {Feature_HasV8_2aBit},
-      {ARM::FeatureFPARMv8, ARM::FeatureFullFP16} },
-    { ARM::AEK_RAS, {Feature_HasV8Bit}, {ARM::FeatureRAS} },
-    { ARM::AEK_LOB, {Feature_HasV8_1MMainlineBit}, {ARM::FeatureLOB} },
-    // FIXME: Unsupported extensions.
-    { ARM::AEK_OS, {}, {} },
-    { ARM::AEK_IWMMXT, {}, {} },
-    { ARM::AEK_IWMMXT2, {}, {} },
-    { ARM::AEK_MAVERICK, {}, {} },
-    { ARM::AEK_XSCALE, {}, {} },
+      {ARM::AEK_CRC, {Feature_HasV8Bit}, {ARM::FeatureCRC}},
+      {ARM::AEK_AES,
+       {Feature_HasV8Bit},
+       {ARM::FeatureAES, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
+      {ARM::AEK_SHA2,
+       {Feature_HasV8Bit},
+       {ARM::FeatureSHA2, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
+      {ARM::AEK_CRYPTO,
+       {Feature_HasV8Bit},
+       {ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
+      {ARM::AEK_FP,
+       {Feature_HasV8Bit},
+       {ARM::FeatureVFP2_SP, ARM::FeatureFPARMv8}},
+      {(ARM::AEK_HWDIVTHUMB | ARM::AEK_HWDIVARM),
+       {Feature_HasV7Bit, Feature_IsNotMClassBit},
+       {ARM::FeatureHWDivThumb, ARM::FeatureHWDivARM}},
+      {ARM::AEK_MP,
+       {Feature_HasV7Bit, Feature_IsNotMClassBit},
+       {ARM::FeatureMP}},
+      {ARM::AEK_SIMD,
+       {Feature_HasV8Bit},
+       {ARM::FeatureNEON, ARM::FeatureVFP2_SP, ARM::FeatureFPARMv8}},
+      {ARM::AEK_SEC, {Feature_HasV6KBit}, {ARM::FeatureTrustZone}},
+      // FIXME: Only available in A-class, isel not predicated
+      {ARM::AEK_VIRT, {Feature_HasV7Bit}, {ARM::FeatureVirtualization}},
+      {ARM::AEK_FP16,
+       {Feature_HasV8_2aBit},
+       {ARM::FeatureFPARMv8, ARM::FeatureFullFP16}},
+      {ARM::AEK_RAS, {Feature_HasV8Bit}, {ARM::FeatureRAS}},
+      {ARM::AEK_LOB, {Feature_HasV8_1MMainlineBit}, {ARM::FeatureLOB}},
+      // FIXME: Unsupported extensions.
+      {ARM::AEK_OS, {}, {}},
+      {ARM::AEK_IWMMXT, {}, {}},
+      {ARM::AEK_IWMMXT2, {}, {}},
+      {ARM::AEK_MAVERICK, {}, {}},
+      {ARM::AEK_XSCALE, {}, {}},
   };
-
-  MCAsmParser &Parser = getParser();
-
-  if (getLexer().isNot(AsmToken::Identifier))
-    return Error(getLexer().getLoc(), "expected architecture extension name");
-
-  StringRef Name = Parser.getTok().getString();
-  SMLoc ExtLoc = Parser.getTok().getLoc();
-  Lex();
-
-  if (parseToken(AsmToken::EndOfStatement,
-                 "unexpected token in '.arch_extension' directive"))
-    return true;
-
   bool EnableFeature = true;
   if (Name.startswith_lower("no")) {
     EnableFeature = false;
@@ -12306,9 +12302,36 @@
     }
     FeatureBitset Features = ComputeAvailableFeatures(STI.getFeatureBits());
     setAvailableFeatures(Features);
-    return false;
+    return true;
+  }
+  return false;
+}
+
+/// parseDirectiveArchExtension
+///   ::= .arch_extension [no]feature
+bool ARMAsmParser::parseDirectiveArchExtension(SMLoc L) {
+
+  MCAsmParser &Parser = getParser();
+
+  if (getLexer().isNot(AsmToken::Identifier))
+    return Error(getLexer().getLoc(), "expected architecture extension name");
+
+  StringRef Name = Parser.getTok().getString();
+  SMLoc ExtLoc = Parser.getTok().getLoc();
+  Lex();
+
+  if (parseToken(AsmToken::EndOfStatement,
+                 "unexpected token in '.arch_extension' directive"))
+    return true;
+
+  if (Name == "nocrypto") {
+    enableArchExtFeature("nosha2", ExtLoc);
+    enableArchExtFeature("noaes", ExtLoc);
   }
 
+  if (enableArchExtFeature(Name, ExtLoc))
+    return false;
+
   return Error(ExtLoc, "unknown architectural extension: " + Name);
 }
 
Index: llvm/lib/Target/ARM/ARMInstrNEON.td
===================================================================
--- llvm/lib/Target/ARM/ARMInstrNEON.td
+++ llvm/lib/Target/ARM/ARMInstrNEON.td
@@ -4371,7 +4371,7 @@
                             v8i16, v8i8, int_arm_neon_vmullp, 1>;
   def  VMULLp64  : N3VLIntnp<0b00101, 0b10, 0b1110, 0, 0, NoItinerary,
                           "vmull", "p64", v2i64, v1i64, int_arm_neon_vmullp, 1>,
-                    Requires<[HasV8, HasCrypto]>;
+                    Requires<[HasV8, HasAES]>;
 }
 defm VMULLsls : N3VLSL_HS<0, 0b1010, IIC_VMULi16D, "vmull", "s", ARMvmulls>;
 defm VMULLslu : N3VLSL_HS<1, 0b1010, IIC_VMULi16D, "vmull", "u", ARMvmullu>;
@@ -7210,33 +7210,31 @@
     DecoderNamespace = "v8Crypto", hasSideEffects = 0 in {
   class AES<string op, bit op7, bit op6, SDPatternOperator Int>
     : N2VQIntXnp<0b00, 0b00, 0b011, op6, op7, NoItinerary,
-                 !strconcat("aes", op), "8", v16i8, v16i8, Int>,
-      Requires<[HasV8, HasCrypto]>;
+                 !strconcat("aes", op), "8", v16i8, v16i8, Int>;
   class AES2Op<string op, bit op7, bit op6, SDPatternOperator Int>
     : N2VQIntX2np<0b00, 0b00, 0b011, op6, op7, NoItinerary,
-                 !strconcat("aes", op), "8", v16i8, v16i8, Int>,
-      Requires<[HasV8, HasCrypto]>;
+                 !strconcat("aes", op), "8", v16i8, v16i8, Int>;
   class N2SHA<string op, bits<2> op17_16, bits<3> op10_8, bit op7, bit op6,
               SDPatternOperator Int>
     : N2VQIntXnp<0b10, op17_16, op10_8, op6, op7, NoItinerary,
-                 !strconcat("sha", op), "32", v4i32, v4i32, Int>,
-      Requires<[HasV8, HasCrypto]>;
+                 !strconcat("sha", op), "32", v4i32, v4i32, Int>;
   class N2SHA2Op<string op, bits<2> op17_16, bits<3> op10_8, bit op7, bit op6,
               SDPatternOperator Int>
     : N2VQIntX2np<0b10, op17_16, op10_8, op6, op7, NoItinerary,
-                 !strconcat("sha", op), "32", v4i32, v4i32, Int>,
-      Requires<[HasV8, HasCrypto]>;
+                 !strconcat("sha", op), "32", v4i32, v4i32, Int>;
   class N3SHA3Op<string op, bits<5> op27_23, bits<2> op21_20, SDPatternOperator Int>
     : N3VQInt3np<op27_23, op21_20, 0b1100, 1, 0, N3RegFrm, NoItinerary,
-                !strconcat("sha", op), "32", v4i32, v4i32, Int, 0>,
-      Requires<[HasV8, HasCrypto]>;
+                !strconcat("sha", op), "32", v4i32, v4i32, Int, 0>;
 }
 
+let Predicates = [HasV8, HasAES] in {
 def AESD : AES2Op<"d", 0, 1, int_arm_neon_aesd>;
 def AESE : AES2Op<"e", 0, 0, int_arm_neon_aese>;
 def AESIMC : AES<"imc", 1, 1, int_arm_neon_aesimc>;
 def AESMC : AES<"mc", 1, 0, int_arm_neon_aesmc>;
+}
 
+let Predicates = [HasV8, HasSHA2] in {
 def SHA1H : N2SHA<"1h", 0b01, 0b010, 1, 1, null_frag>;
 def SHA1SU1 : N2SHA2Op<"1su1", 0b10, 0b011, 1, 0, int_arm_neon_sha1su1>;
 def SHA256SU0 : N2SHA2Op<"256su0", 0b10, 0b011, 1, 1, int_arm_neon_sha256su0>;
@@ -7247,6 +7245,7 @@
 def SHA256H : N3SHA3Op<"256h", 0b00110, 0b00, int_arm_neon_sha256h>;
 def SHA256H2 : N3SHA3Op<"256h2", 0b00110, 0b01, int_arm_neon_sha256h2>;
 def SHA256SU1 : N3SHA3Op<"256su1", 0b00110, 0b10, int_arm_neon_sha256su1>;
+}
 
 let Predicates = [HasNEON] in {
 def : Pat<(i32 (int_arm_neon_sha1h i32:$Rn)),
Index: llvm/lib/Support/ARMTargetParser.cpp
===================================================================
--- llvm/lib/Support/ARMTargetParser.cpp
+++ llvm/lib/Support/ARMTargetParser.cpp
@@ -213,8 +213,9 @@
     const char *PlusName, *MinusName;
     NeonSupportLevel MinSupportLevel;
   } NeonFeatureInfoList[] = {
-    {"+neon", "-neon", NeonSupportLevel::Neon},
-    {"+crypto", "-crypto", NeonSupportLevel::Crypto},
+      {"+neon", "-neon", NeonSupportLevel::Neon},
+      {"+sha2", "-sha2", NeonSupportLevel::Crypto},
+      {"+aes", "-aes", NeonSupportLevel::Crypto},
   };
 
   for (const auto &Info: NeonFeatureInfoList) {
Index: llvm/include/llvm/Support/ARMTargetParser.def
===================================================================
--- llvm/include/llvm/Support/ARMTargetParser.def
+++ llvm/include/llvm/Support/ARMTargetParser.def
@@ -116,14 +116,12 @@
          ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8,
          (ARM::AEK_SEC        | ARM::AEK_MP   | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
           ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP  | ARM::AEK_CRC  | ARM::AEK_RAS |
-          ARM::AEK_DOTPROD    | ARM::AEK_BF16 | ARM::AEK_SHA2 | ARM::AEK_AES |
-          ARM::AEK_I8MM))
+          ARM::AEK_DOTPROD    | ARM::AEK_BF16 | ARM::AEK_I8MM))
 ARM_ARCH("armv8.7-a", ARMV8_7A, "8.7-A", "v8.7a",
          ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8,
          (ARM::AEK_SEC        | ARM::AEK_MP   | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
           ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP  | ARM::AEK_CRC  | ARM::AEK_RAS |
-          ARM::AEK_DOTPROD    | ARM::AEK_BF16 | ARM::AEK_SHA2 | ARM::AEK_AES |
-          ARM::AEK_I8MM))
+          ARM::AEK_DOTPROD    | ARM::AEK_BF16 | ARM::AEK_I8MM))
 ARM_ARCH("armv8-r", ARMV8R, "8-R", "v8r", ARMBuildAttrs::CPUArch::v8_R,
           FK_NEON_FP_ARMV8,
           (ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
Index: clang/test/Preprocessor/arm-target-features.c
===================================================================
--- clang/test/Preprocessor/arm-target-features.c
+++ clang/test/Preprocessor/arm-target-features.c
@@ -862,3 +862,25 @@
 // CHECK-BFLOAT: #define __ARM_BF16_FORMAT_ALTERNATIVE 1
 // CHECK-BFLOAT: #define __ARM_FEATURE_BF16 1
 // CHECK-BFLOAT: #define __ARM_FEATURE_BF16_VECTOR_ARITHMETIC 1
+
+// Check crypto feature test macros
+// RUN: %clang -target arm-arm-none-eabi -march=armv8-a+crypto -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-CRYPTO %s
+// CHECK-CRYPTO: #define __ARM_ARCH_PROFILE 'A'
+// CHECK-CRYPTO: #define __ARM_FEATURE_AES 1
+// CHECK-CRYPTO: #define __ARM_FEATURE_CRYPTO 1
+// CHECK-CRYPTO: #define __ARM_FEATURE_SHA2 1
+// RUN: %clang -target arm-arm-none-eabi -march=armv8-a+nocrypto -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-NOCRYPTO %s
+// CHECK-NOCRYPTO: #define __ARM_ARCH_PROFILE 'A'
+// CHECK-NOCRYPTO-NOT: #define __ARM_FEATURE_AES 1
+// CHECK-NOCRYPTO-NOT: #define __ARM_FEATURE_CRYPTO 1
+// CHECK-NOCRYPTO-NOT: #define __ARM_FEATURE_SHA2 1
+// RUN: %clang -target arm-arm-none-eabi -march=armv8-a+aes+nosha2 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-AES %s
+// CHECK-AES: #define __ARM_ARCH_PROFILE 'A'
+// CHECK-AES: #define __ARM_FEATURE_AES 1
+// CHECK-AES-NOT: #define __ARM_FEATURE_CRYPTO 1
+// CHECK-AES-NOT: #define __ARM_FEATURE_SHA2 1
+// RUN: %clang -target arm-arm-none-eabi -march=armv8-a+noaes+sha2 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-SHA2 %s
+// CHECK-SHA2: #define __ARM_ARCH_PROFILE 'A'
+// CHECK-SHA2-NOT: #define __ARM_FEATURE_AES 1
+// CHECK-SHA2-NOT: #define __ARM_FEATURE_CRYPTO 1
+// CHECK-SHA2: #define __ARM_FEATURE_SHA2 1
Index: clang/test/Preprocessor/aarch64-target-features.c
===================================================================
--- clang/test/Preprocessor/aarch64-target-features.c
+++ clang/test/Preprocessor/aarch64-target-features.c
@@ -15,6 +15,7 @@
 // CHECK-NOT: __ARM_FEATURE_SAT
 // CHECK-NOT: __ARM_FEATURE_SIMD32
 // CHECK: __ARM_ARCH_PROFILE 'A'
+// CHECK-NOT: __ARM_FEATURE_AES
 // CHECK-NOT: __ARM_FEATURE_BIG_ENDIAN
 // CHECK: __ARM_FEATURE_CLZ 1
 // CHECK-NOT: __ARM_FEATURE_CRC32 1
@@ -25,6 +26,11 @@
 // CHECK: __ARM_FEATURE_IDIV 1
 // CHECK: __ARM_FEATURE_LDREX 0xF
 // CHECK: __ARM_FEATURE_NUMERIC_MAXMIN 1
+// CHECK-NOT: __ARM_FEATURE_SHA2 1
+// CHECK-NOT: __ARM_FEATURE_SHA3 1
+// CHECK-NOT: __ARM_FEATURE_SHA512 1
+// CHECK-NOT: __ARM_FEATURE_SM3 1
+// CHECK-NOT: __ARM_FEATURE_SM4 1
 // CHECK: __ARM_FEATURE_UNALIGNED 1
 // CHECK: __ARM_FP 0xE
 // CHECK: __ARM_FP16_ARGS 1
@@ -54,9 +60,36 @@
 // RUN: %clang -target aarch64_be-eabi -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-BIGENDIAN
 // CHECK-BIGENDIAN: __ARM_BIG_ENDIAN 1
 
-// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+crypto -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-CRYPTO %s
-// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a+crypto -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-CRYPTO %s
-// CHECK-CRYPTO: __ARM_FEATURE_CRYPTO 1
+// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+crypto -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-FEAT-CRYPTO %s
+// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a+crypto -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-FEAT-CRYPTO %s
+// CHECK-FEAT-CRYPTO: __ARM_FEATURE_AES 1
+// CHECK-FEAT-CRYPTO: __ARM_FEATURE_CRYPTO 1
+// CHECK-FEAT-CRYPTO: __ARM_FEATURE_SHA2 1
+
+// RUN: %clang -target aarch64-none-linux-gnu -march=armv8.4-a+crypto -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-FEAT-CRYPTO-8_4 %s
+// RUN: %clang -target arm64-none-linux-gnu -march=armv8.4-a+crypto -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-FEAT-CRYPTO-8_4 %s
+// CHECK-FEAT-CRYPTO-8_4: __ARM_FEATURE_AES 1
+// CHECK-FEAT-CRYPTO-8_4: __ARM_FEATURE_CRYPTO 1
+// CHECK-FEAT-CRYPTO-8_4: __ARM_FEATURE_SHA2 1
+// CHECK-FEAT-CRYPTO-8_4: __ARM_FEATURE_SHA3 1
+// CHECK-FEAT-CRYPTO-8_4: __ARM_FEATURE_SHA512 1
+// CHECK-FEAT-CRYPTO-8_4: __ARM_FEATURE_SM3 1
+// CHECK-FEAT-CRYPTO-8_4: __ARM_FEATURE_SM4 1
+
+// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+aes -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-FEAT-AES %s
+// CHECK-FEAT-AES: __ARM_FEATURE_AES 1
+
+// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+sha2 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-FEAT-SHA2 %s
+// CHECK-FEAT-SHA2: __ARM_FEATURE_SHA2 1
+
+// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+sha3 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-FEAT-SHA3 %s
+// CHECK-FEAT-SHA3: __ARM_FEATURE_SHA2 1
+// CHECK-FEAT-SHA3: __ARM_FEATURE_SHA3 1
+// CHECK-FEAT-SHA3: __ARM_FEATURE_SHA512 1
+
+// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+sm4 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-FEAT-SM4 %s
+// CHECK-FEAT-SM4: __ARM_FEATURE_SM3 1
+// CHECK-FEAT-SM4: __ARM_FEATURE_SM4 1
 
 // RUN: %clang -target aarch64-none-linux-gnu -march=armv8.5-a -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-8_5 %s
 // CHECK-8_5: __ARM_FEATURE_FRINT 1
Index: clang/test/Driver/armv8.1m.main.c
===================================================================
--- clang/test/Driver/armv8.1m.main.c
+++ clang/test/Driver/armv8.1m.main.c
@@ -22,7 +22,8 @@
 // CHECK-NOFP-DAG: "-target-feature" "-fp64"
 // CHECK-NOFP-DAG: "-target-feature" "-d32"
 // CHECK-NOFP-DAG: "-target-feature" "-neon"
-// CHECK-NOFP-DAG: "-target-feature" "-crypto"
+// CHECK-NOFP-DAG: "-target-feature" "-sha2"
+// CHECK-NOFP-DAG: "-target-feature" "-aes"
 
 // RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+fp.dp  -### %s 2> %t
 // RUN: FileCheck --check-prefix=CHECK-FPDP < %t %s
Index: clang/test/Driver/arm-mfpu.c
===================================================================
--- clang/test/Driver/arm-mfpu.c
+++ clang/test/Driver/arm-mfpu.c
@@ -34,7 +34,8 @@
 // CHECK-SOFT-ABI-FP-2-DAG: "-target-feature" "-vfp4d16sp"
 // CHECK-SOFT-ABI-FP-2-DAG: "-target-feature" "-fp-armv8d16sp"
 // CHECK-SOFT-ABI-FP-2-DAG: "-target-feature" "-neon"
-// CHECK-SOFT-ABI-FP-2-DAG: "-target-feature" "-crypto"
+// CHECK-SOFT-ABI-FP-2-DAG: "-target-feature" "-sha2"
+// CHECK-SOFT-ABI-FP-2-DAG: "-target-feature" "-aes"
 // CHECK-SOFT-ABI-FP-2-DAG: "-target-feature" "-vfp2sp"
 
 // RUN: %clang -target arm-linux-eabi -mfpu=vfp3 %s -### -o %t.o 2>&1 \
@@ -54,7 +55,8 @@
 // CHECK-SOFT-ABI-FP-3-DAG: "-target-feature" "-vfp4d16sp"
 // CHECK-SOFT-ABI-FP-3-DAG: "-target-feature" "-fp-armv8d16sp"
 // CHECK-SOFT-ABI-FP-3-DAG: "-target-feature" "-neon"
-// CHECK-SOFT-ABI-FP-3-DAG: "-target-feature" "-crypto"
+// CHECK-SOFT-ABI-FP-3-DAG: "-target-feature" "-sha2"
+// CHECK-SOFT-ABI-FP-3-DAG: "-target-feature" "-aes"
 // CHECK-SOFT-ABI-FP-3-DAG: "-target-feature" "-vfp3d16sp"
 
 // RUN: %clang -target arm-linux-eabi -mfpu=vfpv3-fp16 %s -### -o %t.o 2>&1 \
@@ -70,7 +72,8 @@
 // CHECK-VFP3-FP16-DAG: "-target-feature" "+fp64"
 // CHECK-VFP3-FP16-DAG: "-target-feature" "+d32"
 // CHECK-VFP3-FP16-DAG: "-target-feature" "-neon"
-// CHECK-VFP3-FP16-DAG: "-target-feature" "-crypto"
+// CHECK-VFP3-FP16-DAG: "-target-feature" "-sha2"
+// CHECK-VFP3-FP16-DAG: "-target-feature" "-aes"
 
 // RUN: %clang -target arm-linux-eabi -mfpu=vfp3-d16 %s -### -o %t.o 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-VFP3-D16 %s
@@ -100,7 +103,8 @@
 // CHECK-VFP3-D16-FP16-DAG: "-target-feature" "+fp64"
 // CHECK-VFP3-D16-FP16-DAG: "-target-feature" "-d32"
 // CHECK-VFP3-D16-FP16-DAG: "-target-feature" "-neon"
-// CHECK-VFP3-D16-FP16-DAG: "-target-feature" "-crypto"
+// CHECK-VFP3-D16-FP16-DAG: "-target-feature" "-sha2"
+// CHECK-VFP3-D16-FP16-DAG: "-target-feature" "-aes"
 
 // RUN: %clang -target arm-linux-eabi -mfpu=vfpv3xd %s -### -o %t.o 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-VFP3XD %s
@@ -115,7 +119,8 @@
 // CHECK-VFP3XD-DAG: "-target-feature" "-vfp4d16sp"
 // CHECK-VFP3XD-DAG: "-target-feature" "-fp-armv8d16sp"
 // CHECK-VFP3XD-DAG: "-target-feature" "-neon"
-// CHECK-VFP3XD-DAG: "-target-feature" "-crypto"
+// CHECK-VFP3XD-DAG: "-target-feature" "-sha2"
+// CHECK-VFP3XD-DAG: "-target-feature" "-aes"
 
 // RUN: %clang -target arm-linux-eabi -mfpu=vfpv3xd-fp16 %s -### -o %t.o 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-VFP3XD-FP16 %s
@@ -130,7 +135,8 @@
 // CHECK-VFP3XD-FP16-DAG: "-target-feature" "-fp64"
 // CHECK-VFP3XD-FP16-DAG: "-target-feature" "-d32"
 // CHECK-VFP3XD-FP16-DAG: "-target-feature" "-neon"
-// CHECK-VFP3XD-FP16-DAG: "-target-feature" "-crypto"
+// CHECK-VFP3XD-FP16-DAG: "-target-feature" "-sha2"
+// CHECK-VFP3XD-FP16-DAG: "-target-feature" "-aes"
 
 // RUN: %clang -target arm-linux-eabi -mfpu=vfp4 %s -### -o %t.o 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-VFP4 %s
@@ -148,7 +154,8 @@
 // CHECK-SOFT-ABI-FP-4-DAG: "-target-feature" "-vfp3d16sp"
 // CHECK-SOFT-ABI-FP-4-DAG: "-target-feature" "-fp-armv8d16sp"
 // CHECK-SOFT-ABI-FP-4-DAG: "-target-feature" "-neon"
-// CHECK-SOFT-ABI-FP-4-DAG: "-target-feature" "-crypto"
+// CHECK-SOFT-ABI-FP-4-DAG: "-target-feature" "-sha2"
+// CHECK-SOFT-ABI-FP-4-DAG: "-target-feature" "-aes"
 // CHECK-SOFT-ABI-FP-4-DAG: "-target-feature" "-vfp4d16sp"
 
 // RUN: %clang -target arm-linux-eabi -mfpu=vfp4-d16 %s -### -o %t.o 2>&1 \
@@ -191,7 +198,8 @@
 // CHECK-FP5-SP-D16-DAG: "-target-feature" "-neon"
 // CHECK-FP5-SP-D16-DAG: "-target-feature" "-fp64"
 // CHECK-FP5-SP-D16-DAG: "-target-feature" "-d32"
-// CHECK-FP5-SP-D16-DAG: "-target-feature" "-crypto"
+// CHECK-FP5-SP-D16-DAG: "-target-feature" "-sha2"
+// CHECK-FP5-SP-D16-DAG: "-target-feature" "-aes"
 
 // RUN: %clang -target arm-linux-eabi -mfpu=fp5-dp-d16 %s -### -o %t.o 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-FP5-DP-D16 %s
@@ -205,14 +213,16 @@
 // CHECK-FP5-DP-D16-DAG: "-target-feature" "+fp64"
 // CHECK-FP5-DP-D16-DAG: "-target-feature" "-d32"
 // CHECK-FP5-DP-D16-DAG: "-target-feature" "-neon"
-// CHECK-FP5-DP-D16-DAG: "-target-feature" "-crypto"
+// CHECK-FP5-DP-D16-DAG: "-target-feature" "-sha2"
+// CHECK-FP5-DP-D16-DAG: "-target-feature" "-aes"
 // CHECK-SOFT-ABI-FP-5-DAG: "-target-feature" "+soft-float"
 // CHECK-SOFT-ABI-FP-5-DAG: "-target-feature" "+soft-float-abi"
 // CHECK-SOFT-ABI-FP-5-DAG: "-target-feature" "-vfp2sp"
 // CHECK-SOFT-ABI-FP-5-DAG: "-target-feature" "-vfp3d16sp"
 // CHECK-SOFT-ABI-FP-5-DAG: "-target-feature" "-vfp4d16sp"
 // CHECK-SOFT-ABI-FP-5-DAG: "-target-feature" "-neon"
-// CHECK-SOFT-ABI-FP-5-DAG: "-target-feature" "-crypto"
+// CHECK-SOFT-ABI-FP-5-DAG: "-target-feature" "-sha2"
+// CHECK-SOFT-ABI-FP-5-DAG: "-target-feature" "-aes"
 // CHECK-SOFT-ABI-FP-5-DAG: "-target-feature" "-fp-armv8d16sp"
 
 // RUN: %clang -target arm-linux-eabi -mfpu=neon %s -### -o %t.o 2>&1 \
@@ -225,7 +235,8 @@
 // CHECK-SOFT-ABI-FP-6-DAG: "-target-feature" "-vfp2sp"
 // CHECK-SOFT-ABI-FP-6-DAG: "-target-feature" "-vfp4d16sp"
 // CHECK-SOFT-ABI-FP-6-DAG: "-target-feature" "-fp-armv8d16sp"
-// CHECK-SOFT-ABI-FP-6-DAG: "-target-feature" "-crypto"
+// CHECK-SOFT-ABI-FP-6-DAG: "-target-feature" "-sha2"
+// CHECK-SOFT-ABI-FP-6-DAG: "-target-feature" "-aes"
 // CHECK-SOFT-ABI-FP-6-DAG: "-target-feature" "-vfp3d16sp"
 // CHECK-SOFT-ABI-FP-6-DAG: "-target-feature" "-neon"
 
@@ -242,7 +253,8 @@
 // CHECK-NEON-FP16-DAG: "-target-feature" "+fp64"
 // CHECK-NEON-FP16-DAG: "-target-feature" "+d32"
 // CHECK-NEON-FP16-DAG: "-target-feature" "+neon"
-// CHECK-NEON-FP16-DAG: "-target-feature" "-crypto"
+// CHECK-NEON-FP16-DAG: "-target-feature" "-sha2"
+// CHECK-NEON-FP16-DAG: "-target-feature" "-aes"
 
 // RUN: %clang -target arm-linux-eabi -mfpu=neon-vfpv3 %s -### -o %t.o 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-NEON-VFPV3 %s
@@ -265,7 +277,8 @@
 // CHECK-SOFT-ABI-FP-7-DAG: "-target-feature" "-vfp2sp"
 // CHECK-SOFT-ABI-FP-7-DAG: "-target-feature" "-vfp3d16sp"
 // CHECK-SOFT-ABI-FP-7-DAG: "-target-feature" "-fp-armv8d16sp"
-// CHECK-SOFT-ABI-FP-7-DAG: "-target-feature" "-crypto"
+// CHECK-SOFT-ABI-FP-7-DAG: "-target-feature" "-sha2"
+// CHECK-SOFT-ABI-FP-7-DAG: "-target-feature" "-aes"
 // CHECK-SOFT-ABI-FP-7-DAG: "-target-feature" "-vfp4d16sp"
 // CHECK-SOFT-ABI-FP-7-DAG: "-target-feature" "-neon"
 
@@ -279,7 +292,8 @@
 // CHECK-SOFT-ABI-FP-8-DAG: "-target-feature" "-vfp2sp"
 // CHECK-SOFT-ABI-FP-8-DAG: "-target-feature" "-vfp4d16sp"
 // CHECK-SOFT-ABI-FP-8-DAG: "-target-feature" "-fp-armv8d16sp"
-// CHECK-SOFT-ABI-FP-8-DAG: "-target-feature" "-crypto"
+// CHECK-SOFT-ABI-FP-8-DAG: "-target-feature" "-sha2"
+// CHECK-SOFT-ABI-FP-8-DAG: "-target-feature" "-aes"
 // CHECK-SOFT-ABI-FP-8-DAG: "-target-feature" "-vfp3d16sp"
 // CHECK-SOFT-ABI-FP-8-DAG: "-target-feature" "-neon"
 
@@ -289,7 +303,8 @@
 // CHECK-ARMV8-SOFT-FLOAT-DAG: "-target-feature" "+soft-float-abi"
 // NOT-CHECK-ARMV8-SOFT-FLOAT: "-target-feature" "+fp-armv8"
 // CHECK-ARMV9-SOFT-FLOAT-DAG: "-target-feature" "-neon"
-// CHECK-ARMV8-SOFT-FLOAT-DAG: "-target-feature" "-crypto"
+// CHECK-ARMV8-SOFT-FLOAT-DAG: "-target-feature" "-sha2"
+// CHECK-ARMV8-SOFT-FLOAT-DAG: "-target-feature" "-aes"
 
 // RUN: %clang -target armv8-linux-gnueabihf -mfpu=fp-armv8 %s -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-FP-ARMV8 %s
@@ -297,7 +312,8 @@
 // CHECK-FP-ARMV8-NOT: "-target-feature" "+soft-float-abi"
 // CHECK-FP-ARMV8-DAG: "-target-feature" "+fp-armv8"
 // CHECK-FP-ARMV8-DAG: "-target-feature" "-neon"
-// CHECK-FP-ARMV8-DAG: "-target-feature" "-crypto"
+// CHECK-FP-ARMV8-DAG: "-target-feature" "-sha2"
+// CHECK-FP-ARMV8-DAG: "-target-feature" "-aes"
 
 // RUN: %clang -target armv8-linux-gnueabihf -mfpu=neon-fp-armv8 %s -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-NEON-FP-ARMV8 %s
@@ -305,14 +321,16 @@
 // CHECK-NEON-FP-ARMV8-NOT: "-target-feature" "+soft-float-abi"
 // CHECK-NEON-FP-ARMV8-DAG: "-target-feature" "+fp-armv8"
 // CHECK-NEON-FP-ARMV8-DAG: "-target-feature" "+neon"
-// CHECK-NEON-FP-ARMV8-DAG: "-target-feature" "-crypto"
+// CHECK-NEON-FP-ARMV8-DAG: "-target-feature" "-sha2"
+// CHECK-NEON-FP-ARMV8-DAG: "-target-feature" "-aes"
 
 // RUN: %clang -target armv8-linux-gnueabihf -mfpu=crypto-neon-fp-armv8 %s -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-CRYPTO-NEON-FP-ARMV8 %s
 // CHECK-CRYPTO-NEON-FP-ARMV8-NOT: "-target-feature" "+soft-float"
 // CHECK-CRYPTO-NEON-FP-ARMV8-NOT: "-target-feature" "+soft-float-abi"
 // CHECK-CRYPTO-NEON-FP-ARMV8-DAG: "-target-feature" "+fp-armv8"
-// CHECK-CRYPTO-NEON-FP-ARMV8-DAG: "-target-feature" "+crypto"
+// CHECK-CRYPTO-NEON-FP-ARMV8-DAG: "-target-feature" "+sha2"
+// CHECK-CRYPTO-NEON-FP-ARMV8-DAG: "-target-feature" "+aes"
 
 // RUN: %clang -target armv8-linux-gnueabi -mfpu=none %s -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-NO-FP %s
@@ -326,7 +344,8 @@
 // CHECK-NO-FP-DAG: "-target-feature" "-fp64"
 // CHECK-NO-FP-DAG: "-target-feature" "-d32"
 // CHECK-NO-FP-DAG: "-target-feature" "-neon"
-// CHECK-NO-FP-DAG: "-target-feature" "-crypto"
+// CHECK-NO-FP-DAG: "-target-feature" "-sha2"
+// CHECK-NO-FP-DAG: "-target-feature" "-aes"
 
 // RUN: %clang -target arm-linux-gnueabihf %s -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-HF %s
@@ -363,7 +382,8 @@
 // CHECK-SOFT-ABI-FP-DAG: "-target-feature" "-vfp4d16sp"
 // CHECK-SOFT-ABI-FP-DAG: "-target-feature" "-fp-armv8d16sp"
 // CHECK-SOFT-ABI-FP-DAG: "-target-feature" "-neon"
-// CHECK-SOFT-ABI-FP-DAG: "-target-feature" "-crypto"
+// CHECK-SOFT-ABI-FP-DAG: "-target-feature" "-sha2"
+// CHECK-SOFT-ABI-FP-DAG: "-target-feature" "-aes"
 // CHECK-SOFT-ABI-FP-DAG: "-target-feature" "-fpregs"
 
 // RUN: %clang -target arm-linux-androideabi21 %s -### -c 2>&1 \
@@ -375,7 +395,8 @@
 // CHECK-ARM5-ANDROID-FP-DEFAULT-NOT: "-target-feature" "+vfp4"
 // CHECK-ARM5-ANDROID-FP-DEFAULT-NOT: "-target-feature" "+fp-armv8"
 // CHECK-ARM5-ANDROID-FP-DEFAULT-NOT: "-target-feature" "+neon"
-// CHECK-ARM5-ANDROID-FP-DEFAULT-NOT: "-target-feature" "+crypto"
+// CHECK-ARM5-ANDROID-FP-DEFAULT-NOT: "-target-feature" "+sha2"
+// CHECK-ARM5-ANDROID-FP-DEFAULT-NOT: "-target-feature" "+aes"
 
 // RUN: %clang -target armv7-linux-androideabi21 %s -### -c 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-ARM7-ANDROID-FP-DEFAULT %s
@@ -385,7 +406,8 @@
 // CHECK-ARM7-ANDROID-FP-DEFAULT-DAG: "-target-feature" "-vfp4"
 // CHECK-ARM7-ANDROID-FP-DEFAULT-DAG: "-target-feature" "-fp-armv8"
 // CHECK-ARM7-ANDROID-FP-DEFAULT-DAG: "-target-feature" "+neon"
-// CHECK-ARM7-ANDROID-FP-DEFAULT-NOT: "-target-feature" "+crypto"
+// CHECK-ARM7-ANDROID-FP-DEFAULT-NOT: "-target-feature" "+sha2"
+// CHECK-ARM7-ANDROID-FP-DEFAULT-NOT: "-target-feature" "+aes"
 
 // RUN: %clang -target armv7-linux-androideabi21 %s -mfpu=vfp3-d16 -### -c 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-ARM7-ANDROID-FP-D16 %s
@@ -396,7 +418,8 @@
 // CHECK-ARM7-ANDROID-FP-D16-NOT: "-target-feature" "+vfp4"
 // CHECK-ARM7-ANDROID-FP-D16-NOT: "-target-feature" "+fp-armv8"
 // CHECK-ARM7-ANDROID-FP-D16-NOT: "-target-feature" "+neon"
-// CHECK-ARM7-ANDROID-FP-D16-NOT: "-target-feature" "+crypto"
+// CHECK-ARM7-ANDROID-FP-D16-NOT: "-target-feature" "+sha2"
+// CHECK-ARM7-ANDROID-FP-D16-NOT: "-target-feature" "+aes"
 
 // RUN: %clang -target arm-none-none-eabi %s -march=armv8.1-m.main+mve.fp+fp.dp -mfloat-abi=soft -### -c 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-SOFTFLOATABI-INHIBITS-MVE %s
@@ -413,7 +436,8 @@
 // CHECK-MVEFP-FPUNONE-DAG: "-target-feature" "-fp64"
 // CHECK-MVEFP-FPUNONE-DAG: "-target-feature" "-d32"
 // CHECK-MVEFP-FPUNONE-DAG: "-target-feature" "-neon"
-// CHECK-MVEFP-FPUNONE-DAG: "-target-feature" "-crypto"
+// CHECK-MVEFP-FPUNONE-DAG: "-target-feature" "-sha2"
+// CHECK-MVEFP-FPUNONE-DAG: "-target-feature" "-aes"
 // CHECK-MVEFP-FPUNONE-DAG: "-target-feature" "+mve"
 // CHECK-MVEFP-FPUNONE-DAG: "-target-feature" "+dsp"
 // CHECK-MVEFP-FPUNONE-DAG: "-target-feature" "-mve.fp"
@@ -428,7 +452,8 @@
 // CHECK-MVEFP-NOMVE-FPUNONE-DAG: "-target-feature" "-fp64"
 // CHECK-MVEFP-NOMVE-FPUNONE-DAG: "-target-feature" "-d32"
 // CHECK-MVEFP-NOMVE-FPUNONE-DAG: "-target-feature" "-neon"
-// CHECK-MVEFP-NOMVE-FPUNONE-DAG: "-target-feature" "-crypto"
+// CHECK-MVEFP-NOMVE-FPUNONE-DAG: "-target-feature" "-sha2"
+// CHECK-MVEFP-NOMVE-FPUNONE-DAG: "-target-feature" "-aes"
 // CHECK-MVEFP-NOMVE-FPUNONE-DAG: "-target-feature" "+dsp"
 // CHECK-MVEFP-NOMVE-FPUNONE-DAG: "-target-feature" "-mve"
 // CHECK-MVEFP-NOMVE-FPUNONE-DAG: "-target-feature" "-mve.fp"
Index: clang/test/Driver/arm-features.c
===================================================================
--- clang/test/Driver/arm-features.c
+++ clang/test/Driver/arm-features.c
@@ -3,7 +3,7 @@
 // CHECK-CRC: "-cc1"{{.*}} "-triple" "armv8-{{.*}} "-target-cpu" "generic"{{.*}} "-target-feature" "+crc"
 // RUN: %clang -target arm-none-none-eabi -mcpu=generic+crypto -march=armv8a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO %s
 // RUN: %clang -target arm-none-none-eabi -mcpu=generic -march=armv8a+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO %s
-// CHECK-CRYPTO: "-cc1"{{.*}} "-triple" "armv8-{{.*}} "-target-cpu" "generic"{{.*}} "-target-feature" "+crypto"
+// CHECK-CRYPTO: "-cc1"{{.*}} "-triple" "armv8-{{.*}} "-target-cpu" "generic"{{.*}} "-target-feature" "+sha2" "-target-feature" "+aes"
 // RUN: %clang -target arm-none-none-eabi -mcpu=generic+dsp -march=armv8m.main -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-DSP %s
 // RUN: %clang -target arm-none-none-eabi -mcpu=generic -march=armv8m.main+dsp -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-DSP %s
 // CHECK-DSP: "-cc1"{{.*}} "-triple" "thumbv8m.main-{{.*}} "-target-cpu" "generic"{{.*}} "-target-feature" "+dsp"
@@ -13,7 +13,7 @@
 // CHECK-NOCRC: "-cc1"{{.*}} "-triple" "armv8-{{.*}} "-target-cpu" "generic"{{.*}} "-target-feature" "-crc"
 // RUN: %clang -target arm-none-none-eabi -mcpu=generic+nocrypto -march=armv8a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO %s
 // RUN: %clang -target arm-none-none-eabi -mcpu=generic -march=armv8a+nocrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO %s
-// CHECK-NOCRYPTO: "-cc1"{{.*}} "-triple" "armv8-{{.*}} "-target-cpu" "generic"{{.*}} "-target-feature" "-crypto"
+// CHECK-NOCRYPTO: "-cc1"{{.*}} "-triple" "armv8-{{.*}} "-target-cpu" "generic"{{.*}} "-target-feature" "-sha2" "-target-feature" "-aes"
 // RUN: %clang -target arm-none-none-eabi -mcpu=generic+nodsp -march=armv8m.main -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NODSP %s
 // RUN: %clang -target arm-none-none-eabi -mcpu=generic -march=armv8m.main+nodsp -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NODSP %s
 // CHECK-NODSP: "-cc1"{{.*}} "-triple" "thumbv8m.main-{{.*}} "-target-cpu" "generic"{{.*}} "-target-feature" "-dsp"
@@ -38,7 +38,7 @@
 // RUN: %clang -target arm-arm-none-eabi -march=armv8.3a+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO2 %s
 // RUN: %clang -target arm-arm-none-eabi -march=armv8.4a+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO2 %s
 // RUN: %clang -target arm-arm-none-eabi -march=armv8.5a+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO2 %s
-// CHECK-CRYPTO2: "-cc1"{{.*}} "-target-cpu" "generic"{{.*}} "-target-feature" "+crypto"{{.*}} "-target-feature" "+sha2" "-target-feature" "+aes"
+// CHECK-CRYPTO2: "-cc1"{{.*}} "-target-cpu" "generic"{{.*}} "-target-feature" "+sha2" "-target-feature" "+aes"
 //
 // Check -crypto:
 //
@@ -47,22 +47,22 @@
 // RUN: %clang -target arm-arm-none-eabi -march=armv8.3a+nocrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO2 %s
 // RUN: %clang -target arm-arm-none-eabi -march=armv8.4a+nocrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO2 %s
 // RUN: %clang -target arm-arm-none-eabi -march=armv8.5a+nocrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO2 %s
-// CHECK-NOCRYPTO2-NOT: "-target-feature" "+crypto" "-target-feature" "+sha2" "-target-feature" "+aes"
+// CHECK-NOCRYPTO2: "-cc1"{{.*}} "-target-cpu" "generic"{{.*}} "-target-feature" "-sha2" "-target-feature" "-aes"
 //
 // RUN: %clang -target arm-arm-none-eabi -mcpu=cortex-a57+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO2-CPU %s
 // RUN: %clang -target arm-arm-none-eabi -mcpu=cortex-a57 -mfpu=crypto-neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO2-CPU %s
-// CHECK-CRYPTO2-CPU: "-cc1"{{.*}} "-target-cpu" "cortex-a57"{{.*}} "-target-feature" "+crypto"{{.*}} "-target-feature" "+sha2" "-target-feature" "+aes"
+// CHECK-CRYPTO2-CPU: "-cc1"{{.*}} "-target-cpu" "cortex-a57"{{.*}} "-target-feature" "+sha2" "-target-feature" "+aes"
 //
-// RUN: %clang -target arm-arm-none-eabi -mcpu=cortex-a57+norypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO2-CPU %s
+// RUN: %clang -target arm-arm-none-eabi -mcpu=cortex-a57+nocrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO2-CPU %s
 // RUN: %clang -target arm-arm-none-eabi -mcpu=cortex-a57 -mfpu=neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO2-CPU %s
-// CHECK-NOCRYPTO2-CPU-NOT: "-cc1"{{.*}} "-target-cpu" "cortex-a57"{{.*}} "-target-feature" "+crypto"{{.*}} "-target-feature" "+sha2" "-target-feature" "+aes"
+// CHECK-NOCRYPTO2-CPU: "-cc1"{{.*}} "-target-cpu" "cortex-a57"{{.*}} "-target-feature" "-sha2" "-target-feature" "-aes"
 //
 // Check +crypto -sha2 -aes:
 //
 // RUN: %clang -target arm-arm-none-eabi -march=armv8.1a+crypto+nosha2+noaes -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO3 %s
 // RUN: %clang -target arm-arm-none-eabi -mcpu=cortex-a57+crypto+nosha2+noaes -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO3 %s
 // RUN: %clang -target arm-arm-none-eabi -mcpu=cortex-a57+nosha2+noaes -mfpu=crypto-neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO3 %s
-// CHECK-CRYPTO3-NOT: "-target-feature" "+sha2" "-target-feature" "+aes"
+// CHECK-CRYPTO3: "-target-feature" "-sha2" "-target-feature" "-aes"
 //
 // Check -crypto +sha2 +aes:
 //
@@ -73,24 +73,27 @@
 //
 // Check +crypto for M and R profiles:
 //
-// RUN: %clang -target arm-arm-none-eabi -march=armv8-r+crypto   -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO5 %s
+// RUN: %clang -target arm-arm-none-eabi -march=armv8-r+crypto   -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO-R %s
+// CHECK-CRYPTO-R: "-cc1"{{.*}} "-target-cpu" "cortex-r52"{{.*}} "-target-feature" "+sha2" "-target-feature" "+aes"
 // RUN: %clang -target arm-arm-none-eabi -march=armv8-m.base+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO5 %s
 // RUN: %clang -target arm-arm-none-eabi -march=armv8-m.main+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO5 %s
 // RUN: %clang -target arm-arm-none-eabi -mcpu=cortex-m23+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO5 %s
-// CHECK-NOCRYPTO5: warning: ignoring extension 'crypto' because the {{.*}} architecture does not support it
-// CHECK-NOCRYPTO5-NOT: "-target-feature" "+crypto"{{.*}} "-target-feature" "+sha2" "-target-feature" "+aes"
+// CHECK-NOCRYPTO5: warning: ignoring extension 'sha2' because the {{.*}} architecture does not support it
+// CHECK-NOCRYPTO5: warning: ignoring extension 'aes' because the {{.*}} architecture does not support it
+// CHECK-NOCRYPTO5: "-target-feature" "-sha2" "-target-feature" "-aes"
 //
 // Check +crypto does not affect -march=armv7a -mfpu=crypto-neon-fp-armv8, but it does warn that +crypto has no effect
-// RUN: %clang -target arm-none-none-eabi -fno-integrated-as -march=armv7a -mfpu=crypto-neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefixes=CHECK-WARNONLY,ALL %s
-// RUN: %clang -target arm-none-none-eabi -fno-integrated-as -march=armv7a+aes -mfpu=crypto-neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefixes=CHECK-WARNONLY,ALL,CHECK-HASAES %s
-// RUN: %clang -target arm-none-none-eabi -fno-integrated-as -march=armv7a+sha2 -mfpu=crypto-neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefixes=CHECK-WARNONLY,ALL,CHECK-HASSHA %s
-// RUN: %clang -target arm-none-none-eabi -fno-integrated-as -march=armv7a+sha2+aes -mfpu=crypto-neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefixes=CHECK-WARNONLY,ALL,CHECK-HASSHA,CHECK-HASAES %s
-// RUN: %clang -target arm-none-none-eabi -fno-integrated-as -march=armv7a+aes -mfpu=neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefixes=ALL,CHECK-HASAES %s
-// RUN: %clang -target arm-none-none-eabi -fno-integrated-as -march=armv7a+sha2 -mfpu=neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefixes=ALL,CHECK-HASSHA %s
-// RUN: %clang -target arm-none-none-eabi -fno-integrated-as -march=armv7a+sha2+aes -mfpu=neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefixes=ALL,CHECK-HASSHA,CHECK-HASAES %s
-// CHECK-WARNONLY: warning: ignoring extension 'crypto' because the 'armv7-a' architecture does not support it
-// ALL:     "-target-feature"
-// CHECK-WARNONLY-NOT: "-target-feature" "-crypto"
-// CHECK-HASSHA-SAME:  "-target-feature" "+sha2"
-// CHECK-HASAES-SAME:  "-target-feature" "+aes"
+// RUN: %clang -target arm-none-none-eabi -fno-integrated-as -march=armv7a -mfpu=crypto-neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefixes=CHECK-WARNSHA,CHECK-WARNAES,CHECK-HASSHA,CHECK-HASAES %s
+// RUN: %clang -target arm-none-none-eabi -fno-integrated-as -march=armv7a+aes -mfpu=crypto-neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefixes=CHECK-WARNSHA,CHECK-WARNAES,CHECK-HASSHA,CHECK-HASAES %s
+// RUN: %clang -target arm-none-none-eabi -fno-integrated-as -march=armv7a+sha2 -mfpu=crypto-neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefixes=CHECK-WARNSHA,CHECK-WARNAES,CHECK-HASSHA,CHECK-HASAES %s
+// RUN: %clang -target arm-none-none-eabi -fno-integrated-as -march=armv7a+sha2+aes -mfpu=crypto-neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefixes=CHECK-WARNSHA,CHECK-WARNAES,CHECK-HASSHA,CHECK-HASAES %s
+// RUN: %clang -target arm-none-none-eabi -fno-integrated-as -march=armv7a+aes -mfpu=neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefixes=CHECK-WARNAES,CHECK-HASAES,CHECK-NOSHA %s
+// RUN: %clang -target arm-none-none-eabi -fno-integrated-as -march=armv7a+sha2 -mfpu=neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefixes=CHECK-WARNSHA,CHECK-HASSHA,CHECK-NOAES %s
+// RUN: %clang -target arm-none-none-eabi -fno-integrated-as -march=armv7a+sha2+aes -mfpu=neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefixes=CHECK-WARNSHA,CHECK-WARNAES,CHECK-HASSHA,CHECK-HASAES %s
+// CHECK-WARNSHA: warning: ignoring extension 'sha2' because the 'armv7-a' architecture does not support it
+// CHECK-WARNAES: warning: ignoring extension 'aes' because the 'armv7-a' architecture does not support it
+// CHECK-HASSHA-DAG: "-target-feature" "+sha2"
+// CHECK-HASAES-DAG: "-target-feature" "+aes"
+// CHECK-NOSHA-DAG: "-target-feature" "-sha2"
+// CHECK-NOAES-DAG: "-target-feature" "-aes"
 //
Index: clang/test/Driver/arm-cortex-cpus.c
===================================================================
--- clang/test/Driver/arm-cortex-cpus.c
+++ clang/test/Driver/arm-cortex-cpus.c
@@ -408,7 +408,7 @@
 // CHECK-V82A-FP16-NOFP16FML: "-target-feature" "+fullfp16" "-target-feature" "-fp16fml"
 
 // RUN: %clang -target armv8a-linux-eabi -march=armv8.2-a+nofp16fml+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V82A-NOFP16FML-FP16 %s
-// CHECK-V82A-NOFP16FML-FP16: "-target-feature" "-fp16fml" "-target-feature" "+fullfp16"
+// CHECK-V82A-NOFP16FML-FP16: "-target-feature" "+fullfp16" "-target-feature" "-fp16fml"
 
 // RUN: %clang -target armv8a-linux-eabi -march=armv8.2-a+fp16fml+nofp16 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V82A-FP16FML-NOFP16 %s
 // CHECK-V82A-FP16FML-NOFP16: "-target-feature" "-fullfp16" "-target-feature" "-fp16fml"
@@ -433,7 +433,7 @@
 // CHECK-V83A-FP16-NOFP16FML: "-target-feature" "+fullfp16" "-target-feature" "-fp16fml"
 
 // RUN: %clang -target armv8a-linux-eabi -march=armv8.3-a+nofp16fml+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V83A-NOFP16FML-FP16 %s
-// CHECK-V83A-NOFP16FML-FP16: "-target-feature" "-fp16fml" "-target-feature" "+fullfp16"
+// CHECK-V83A-NOFP16FML-FP16: "-target-feature" "+fullfp16" "-target-feature" "-fp16fml"
 
 // RUN: %clang -target armv8a-linux-eabi -march=armv8.3-a+fp16fml+nofp16 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V83A-FP16FML-NOFP16 %s
 // CHECK-V83A-FP16FML-NOFP16: "-target-feature" "-fullfp16" "-target-feature" "-fp16fml"
@@ -826,7 +826,8 @@
 // RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a73 -mfloat-abi=soft -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A73-SOFT %s
 // CHECK-CORTEX-A73: "-cc1"{{.*}} "-triple" "armv8-{{.*}} "-target-cpu" "cortex-a73"
 // CHECK-CORTEX-A73-MFPU: "-cc1"{{.*}} "-target-feature" "+fp-armv8"
-// CHECK-CORTEX-A73-MFPU: "-target-feature" "+crypto"
+// CHECK-CORTEX-A73-MFPU: "-target-feature" "+sha2"
+// CHECK-CORTEX-A73-MFPU: "-target-feature" "+aes"
 // CHECK-CORTEX-A73-SOFT: "-target-feature" "+soft-float"
 // CHECK-CORTEX-A73-SOFT: "-target-feature" "+soft-float-abi"
 
@@ -835,7 +836,8 @@
 // RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a75 -mfloat-abi=soft -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A75-SOFT %s
 // CHECK-CORTEX-A75: "-cc1"{{.*}} "-triple" "armv8.2a-{{.*}} "-target-cpu" "cortex-a75"
 // CHECK-CORTEX-A75-MFPU: "-cc1"{{.*}} "-target-feature" "+fp-armv8"
-// CHECK-CORTEX-A75-MFPU: "-target-feature" "+crypto"
+// CHECK-CORTEX-A75-MFPU: "-target-feature" "+sha2"
+// CHECK-CORTEX-A75-MFPU: "-target-feature" "+aes"
 // CHECK-CORTEX-A75-SOFT: "-target-feature" "+soft-float"
 // CHECK-CORTEX-A75-SOFT: "-target-feature" "+soft-float-abi"
 
@@ -844,7 +846,8 @@
 // RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a76 -mfloat-abi=soft -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A76-SOFT %s
 // CHECK-CORTEX-A76: "-cc1"{{.*}} "-triple" "armv8.2a-{{.*}} "-target-cpu" "cortex-a76"
 // CHECK-CORTEX-A76-MFPU: "-cc1"{{.*}} "-target-feature" "+fp-armv8"
-// CHECK-CORTEX-A76-MFPU: "-target-feature" "+crypto"
+// CHECK-CORTEX-A76-MFPU: "-target-feature" "+sha2"
+// CHECK-CORTEX-A76-MFPU: -target-feature" "+aes"
 // CHECK-CORTEX-A76-SOFT: "-target-feature" "+soft-float"
 // CHECK-CORTEX-A76-SOFT: "-target-feature" "+soft-float-abi"
 
@@ -853,7 +856,8 @@
 // RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a76ae -mfloat-abi=soft -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A76AE-SOFT %s
 // CHECK-CORTEX-A76AE: "-cc1"{{.*}} "-triple" "armv8.2a-{{.*}} "-target-cpu" "cortex-a76ae"
 // CHECK-CORTEX-A76AE-MFPU: "-cc1"{{.*}} "-target-feature" "+fp-armv8"
-// CHECK-CORTEX-A76AE-MFPU: "-target-feature" "+crypto"
+// CHECK-CORTEX-A76AE-MFPU: "-target-feature" "+sha2"
+// CHECK-CORTEX-A76AE-MFPU: -target-feature" "+aes"
 // CHECK-CORTEX-A76AE-SOFT: "-target-feature" "+soft-float"
 // CHECK-CORTEX-A76AE-SOFT: "-target-feature" "+soft-float-abi"
 
@@ -877,13 +881,22 @@
 // RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-x1 -mfpu=crypto-neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-X1-MFPU %s
 // CHECK-CORTEX-X1: "-cc1"{{.*}} "-triple" "armv8.2a-{{.*}} "-target-cpu" "cortex-x1"
 // CHECK-CORTEX-X1-MFPU: "-cc1"{{.*}} "-target-feature" "+fp-armv8"
-// CHECK-CORTEX-X1-MFPU: "-target-feature" "+crypto"
+// CHECK-CORTEX-X1-MFPU: "-target-feature" "+sha2"
+// CHECK-CORTEX-X1-MFPU: "-target-feature" "+aes"
 
 // RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a78 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A78 %s
 // RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a78 -mfpu=crypto-neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A78-MFPU %s
 // CHECK-CORTEX-A78: "-cc1"{{.*}} "-triple" "armv8.2a-{{.*}} "-target-cpu" "cortex-a78"
 // CHECK-CORTEX-A78-MFPU: "-cc1"{{.*}} "-target-feature" "+fp-armv8"
-// CHECK-CORTEX-A78-MFPU: "-target-feature" "+crypto"
+// CHECK-CORTEX-A78-MFPU: "-target-feature" "+sha2"
+// CHECK-CORTEX-A78-MFPU: "-target-feature" "+aes"
+
+// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a78c -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A78C %s
+// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a78c -mfpu=crypto-neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A78C-MFPU %s
+// CHECK-CORTEX-A78C: "-cc1"{{.*}} "-triple" "armv8.2a-{{.*}} "-target-cpu" "cortex-a78c"
+// CHECK-CORTEX-A78C-MFPU: "-cc1"{{.*}} "-target-feature" "+fp-armv8"
+// CHECK-CORTEX-A78C-MFPU: "-target-feature" "+sha2"
+// CHECK-CORTEX-A78C-MFPU: "-target-feature" "+aes"
 
 // RUN: %clang -target arm -mcpu=cortex-m23 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8MBASE %s
 // CHECK-CPUV8MBASE:  "-cc1"{{.*}} "-triple" "thumbv8m.base-
Index: clang/test/Driver/aarch64-cpus.c
===================================================================
--- clang/test/Driver/aarch64-cpus.c
+++ clang/test/Driver/aarch64-cpus.c
@@ -483,12 +483,6 @@
 // MCPU-MTUNE-THUNDERX2T99: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "thunderx2t99"
 // MCPU-MTUNE-THUNDERX3T110: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "thunderx3t110"
 
-// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a78c -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A78C %s
-// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a78c -mfpu=crypto-neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A78C-MFPU %s
-// CHECK-CORTEX-A78C: "-cc1"{{.*}} "-triple" "armv8.2a-{{.*}} "-target-cpu" "cortex-a78c"
-// CHECK-CORTEX-A78C-MFPU: "-cc1"{{.*}} "-target-feature" "+fp-armv8"
-// CHECK-CORTEX-A78C-MFPU: "-target-feature" "+crypto"
-
 // RUN: %clang -target aarch64 -march=armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A %s
 // RUN: %clang -target aarch64 -march=armv8.1-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A %s
 // RUN: %clang -target aarch64 -mlittle-endian -march=armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A %s
Index: clang/test/CodeGen/neon-crypto.c
===================================================================
--- clang/test/CodeGen/neon-crypto.c
+++ clang/test/CodeGen/neon-crypto.c
@@ -1,8 +1,10 @@
 // RUN: %clang_cc1 -triple arm-none-linux-gnueabi -target-feature +neon \
-// RUN:  -target-feature +crypto -target-cpu cortex-a57 -emit-llvm -O1 -o - %s | FileCheck %s
+// RUN:  -target-feature +sha2 -target-feature +aes \
+// RUN:  -target-cpu cortex-a57 -emit-llvm -O1 -o - %s | FileCheck %s
 
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
-// RUN:   -target-feature +crypto -emit-llvm -O1 -o - %s | FileCheck %s
+// RUN:   -target-feature +sha2 -target-feature +aes \
+// RUN:   -emit-llvm -O1 -o - %s | FileCheck %s
 // RUN: not %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:   -S -O3 -o - %s 2>&1 | FileCheck --check-prefix=CHECK-NO-CRYPTO %s
 
Index: clang/test/CodeGen/arm64_crypto.c
===================================================================
--- clang/test/CodeGen/arm64_crypto.c
+++ clang/test/CodeGen/arm64_crypto.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-feature +neon -target-feature +crypto -ffreestanding -Os -S -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-feature +neon -target-feature +crypto -ffreestanding -fexperimental-new-pass-manager -Os -S -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-feature +neon -target-feature +aes -target-feature +sha2 -ffreestanding -Os -S -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-feature +neon -target-feature +aes -target-feature +sha2 -ffreestanding -fexperimental-new-pass-manager -Os -S -o - %s | FileCheck %s
 // REQUIRES: aarch64-registered-target
 
 #include <arm_neon.h>
Index: clang/test/CodeGen/arm-target-features.c
===================================================================
--- clang/test/CodeGen/arm-target-features.c
+++ clang/test/CodeGen/arm-target-features.c
@@ -26,14 +26,14 @@
 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a72 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8
 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a73 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8
 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu exynos-m3 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8
-// CHECK-BASIC-V8: "target-features"="+armv8-a,+crc,+crypto,+d32,+dsp,+fp-armv8,+fp-armv8d16,+fp-armv8d16sp,+fp-armv8sp,+fp16,+fp64,+hwdiv,+hwdiv-arm,+neon,+thumb-mode,+vfp2,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,+vfp4,+vfp4d16,+vfp4d16sp,+vfp4sp"
+// CHECK-BASIC-V8: "target-features"="+aes,+armv8-a,+crc,+d32,+dsp,+fp-armv8,+fp-armv8d16,+fp-armv8d16sp,+fp-armv8sp,+fp16,+fp64,+hwdiv,+hwdiv-arm,+neon,+sha2,+thumb-mode,+vfp2,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,+vfp4,+vfp4d16,+vfp4d16sp,+vfp4sp"
 
 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu exynos-m4 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V82
 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu exynos-m5 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V82
-// CHECK-BASIC-V82: "target-features"="+armv8.2-a,+crc,+crypto,+d32,+dotprod,+dsp,+fp-armv8,+fp-armv8d16,+fp-armv8d16sp,+fp-armv8sp,+fp16,+fp64,+fullfp16,+hwdiv,+hwdiv-arm,+neon,+ras,+thumb-mode,+vfp2,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,+vfp4,+vfp4d16,+vfp4d16sp,+vfp4sp"
+// CHECK-BASIC-V82: "target-features"="+aes,+armv8.2-a,+crc,+d32,+dotprod,+dsp,+fp-armv8,+fp-armv8d16,+fp-armv8d16sp,+fp-armv8sp,+fp16,+fp64,+fullfp16,+hwdiv,+hwdiv-arm,+neon,+ras,+sha2,+thumb-mode,+vfp2,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,+vfp4,+vfp4d16,+vfp4d16sp,+vfp4sp"
 
 // RUN: %clang_cc1 -triple armv8-linux-gnueabi -target-cpu cortex-a53 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8-ARM
-// CHECK-BASIC-V8-ARM: "target-features"="+armv8-a,+crc,+crypto,+d32,+dsp,+fp-armv8,+fp-armv8d16,+fp-armv8d16sp,+fp-armv8sp,+fp16,+fp64,+hwdiv,+hwdiv-arm,+neon,+vfp2,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,+vfp4,+vfp4d16,+vfp4d16sp,+vfp4sp,-thumb-mode"
+// CHECK-BASIC-V8-ARM: "target-features"="+aes,+armv8-a,+crc,+d32,+dsp,+fp-armv8,+fp-armv8d16,+fp-armv8d16sp,+fp-armv8sp,+fp16,+fp64,+hwdiv,+hwdiv-arm,+neon,+sha2,+vfp2,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,+vfp4,+vfp4d16,+vfp4d16sp,+vfp4sp,-thumb-mode"
 
 // RUN: %clang_cc1 -triple thumbv7-linux-gnueabi -target-cpu cortex-r5 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP3-D16-DIV
 // CHECK-VFP3-D16-DIV: "target-features"="+armv7-r,+dsp,+fp64,+hwdiv,+hwdiv-arm,+thumb-mode,+vfp2,+vfp2sp,+vfp3d16,+vfp3d16sp"
Index: clang/test/CodeGen/aarch64-neon-sm4-sm3.c
===================================================================
--- clang/test/CodeGen/aarch64-neon-sm4-sm3.c
+++ clang/test/CodeGen/aarch64-neon-sm4-sm3.c
@@ -1,13 +1,10 @@
 // RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon \
-// RUN:  -target-feature +crypto -S -emit-llvm -o - %s \
+// RUN:  -target-feature +sm4 -S -emit-llvm -o - %s \
 // RUN:  | FileCheck %s
 
 // RUN: not %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon \
 // RUN: -S -emit-llvm -o - %s 2>&1 | FileCheck --check-prefix=CHECK-NO-CRYPTO %s
 
-//The front-end requires the addition of both +crypto and +sm4 in the 
-// command line, however the back-end requires only +sm4 (includes sm4&sm3)
-
 #include <arm_neon.h>
 
 void test_vsm3partw1(uint32x4_t a, uint32x4_t b, uint32x4_t c) {
Index: clang/test/CodeGen/aarch64-neon-sha3.c
===================================================================
--- clang/test/CodeGen/aarch64-neon-sha3.c
+++ clang/test/CodeGen/aarch64-neon-sha3.c
@@ -1,6 +1,6 @@
 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
 // RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon \
-// RUN:  -target-feature +crypto -S -emit-llvm -o - %s \
+// RUN:  -target-feature +sha3 -S -emit-llvm -o - %s \
 // RUN:  | FileCheck %s
 
 #include <arm_neon.h>
Index: clang/test/CodeGen/aarch64-neon-range-checks.c
===================================================================
--- clang/test/CodeGen/aarch64-neon-range-checks.c
+++ clang/test/CodeGen/aarch64-neon-range-checks.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -target-feature +crypto -verify %s
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -target-feature +sha3 -target-feature +sm4 -verify %s
 
 #include <arm_neon.h>
 
Index: clang/lib/Driver/ToolChains/Arch/ARM.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Arch/ARM.cpp
+++ clang/lib/Driver/ToolChains/Arch/ARM.cpp
@@ -541,6 +541,14 @@
     if (!llvm::ARM::getFPUFeatures(FPUID, Features))
       D.Diag(clang::diag::err_drv_clang_unsupported)
           << std::string("-mfpu=") + AndroidFPU;
+  } else {
+    if (!ForAS) {
+      std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple);
+      llvm::ARM::ArchKind ArchKind =
+          arm::getLLVMArchKindForARM(CPU, ArchName, Triple);
+      FPUID = llvm::ARM::getDefaultFPU(CPU, ArchKind);
+      (void)llvm::ARM::getFPUFeatures(FPUID, Features);
+    }
   }
 
   // Now we've finished accumulating features from arch, cpu and fpu,
@@ -618,34 +626,69 @@
       Features.push_back("-crc");
   }
 
-  // For Arch >= ARMv8.0 && A profile:  crypto = sha2 + aes
+  // For Arch >= ARMv8.0 && A or R profile:  crypto = sha2 + aes
+  // Rather than replace within the feature vector, determine whether each
+  // algorithm is enabled and append this to the end of the vector.
+  // The algorithms can be controlled by their specific feature or the crypto
+  // feature, so their status can be determined by the last occurance of
+  // either in the vector. This allows one to supercede the other.
+  // e.g. +crypto+noaes in -march/-mcpu should enable sha2, but not aes
   // FIXME: this needs reimplementation after the TargetParser rewrite
-  auto CryptoIt = llvm::find_if(llvm::reverse(Features), [](const StringRef F) {
-    return F.contains("crypto");
-  });
-  if (CryptoIt != Features.rend()) {
-    if (CryptoIt->take_front() == "+") {
-      StringRef ArchSuffix = arm::getLLVMArchSuffixForARM(
-          arm::getARMTargetCPU(CPUName, ArchName, Triple), ArchName, Triple);
-      if (llvm::ARM::parseArchVersion(ArchSuffix) >= 8 &&
-          llvm::ARM::parseArchProfile(ArchSuffix) ==
-              llvm::ARM::ProfileKind::A) {
-        if (ArchName.find_lower("+nosha2") == StringRef::npos &&
-            CPUName.find_lower("+nosha2") == StringRef::npos)
-          Features.push_back("+sha2");
-        if (ArchName.find_lower("+noaes") == StringRef::npos &&
-            CPUName.find_lower("+noaes") == StringRef::npos)
-          Features.push_back("+aes");
-      } else {
+  bool HasSHA2 = false;
+  bool HasAES = false;
+  const auto ItSHA2 =
+      llvm::find_if(llvm::reverse(Features), [](const StringRef F) {
+        return F.contains("crypto") || F.contains("sha2");
+      });
+  const auto ItAES =
+      llvm::find_if(llvm::reverse(Features), [](const StringRef F) {
+        return F.contains("crypto") || F.contains("aes");
+      });
+  const bool FoundSHA2 = ItSHA2 != Features.rend();
+  const bool FoundAES = ItAES != Features.rend();
+  if (FoundSHA2)
+    HasSHA2 = ItSHA2->take_front() == "+";
+  if (FoundAES)
+    HasAES = ItAES->take_front() == "+";
+  if (FoundSHA2 || FoundAES) {
+    if (HasSHA2 && HasAES)
+      Features.push_back("+crypto");
+    else
+      Features.push_back("-crypto");
+    if (HasSHA2)
+      Features.push_back("+sha2");
+    else
+      Features.push_back("-sha2");
+    if (HasAES)
+      Features.push_back("+aes");
+    else
+      Features.push_back("-aes");
+  }
+
+  if (HasSHA2 || HasAES) {
+    StringRef ArchSuffix = arm::getLLVMArchSuffixForARM(
+        arm::getARMTargetCPU(CPUName, ArchName, Triple), ArchName, Triple);
+    llvm::ARM::ProfileKind ArchProfile =
+        llvm::ARM::parseArchProfile(ArchSuffix);
+    if (!((llvm::ARM::parseArchVersion(ArchSuffix) >= 8) &&
+          (ArchProfile == llvm::ARM::ProfileKind::A ||
+           ArchProfile == llvm::ARM::ProfileKind::R))) {
+      if (HasSHA2)
+        D.Diag(clang::diag::warn_target_unsupported_extension)
+            << "sha2"
+            << llvm::ARM::getArchName(llvm::ARM::parseArch(ArchSuffix));
+      if (HasAES)
         D.Diag(clang::diag::warn_target_unsupported_extension)
-            << "crypto"
+            << "aes"
             << llvm::ARM::getArchName(llvm::ARM::parseArch(ArchSuffix));
-        // With -fno-integrated-as -mfpu=crypto-neon-fp-armv8 some assemblers such as the GNU assembler
-        // will permit the use of crypto instructions as the fpu will override the architecture.
-        // We keep the crypto feature in this case to preserve compatibility.
-        // In all other cases we remove the crypto feature.
-        if (!Args.hasArg(options::OPT_fno_integrated_as))
-          Features.push_back("-crypto");
+      // With -fno-integrated-as -mfpu=crypto-neon-fp-armv8 some assemblers such
+      // as the GNU assembler will permit the use of crypto instructions as the
+      // fpu will override the architecture. We keep the crypto feature in this
+      // case to preserve compatibility. In all other cases we remove the crypto
+      // feature.
+      if (!Args.hasArg(options::OPT_fno_integrated_as)) {
+        Features.push_back("-sha2");
+        Features.push_back("-aes");
       }
     }
   }
Index: clang/lib/Basic/Targets/ARM.h
===================================================================
--- clang/lib/Basic/Targets/ARM.h
+++ clang/lib/Basic/Targets/ARM.h
@@ -72,6 +72,8 @@
 
   unsigned CRC : 1;
   unsigned Crypto : 1;
+  unsigned SHA2 : 1;
+  unsigned AES : 1;
   unsigned DSP : 1;
   unsigned Unaligned : 1;
   unsigned DotProd : 1;
Index: clang/lib/Basic/Targets/ARM.cpp
===================================================================
--- clang/lib/Basic/Targets/ARM.cpp
+++ clang/lib/Basic/Targets/ARM.cpp
@@ -426,6 +426,8 @@
   MVE = 0;
   CRC = 0;
   Crypto = 0;
+  SHA2 = 0;
+  AES = 0;
   DSP = 0;
   Unaligned = 1;
   SoftFloat = false;
@@ -476,6 +478,10 @@
       CRC = 1;
     } else if (Feature == "+crypto") {
       Crypto = 1;
+    } else if (Feature == "+sha2") {
+      SHA2 = 1;
+    } else if (Feature == "+aes") {
+      AES = 1;
     } else if (Feature == "+dsp") {
       DSP = 1;
     } else if (Feature == "+fp64") {
@@ -639,8 +645,14 @@
 
   if (ArchVersion >= 8) {
     // ACLE 6.5.7 Crypto Extension
-    if (Crypto)
+    // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained
+    // feature macros for AES and SHA2
+    if (Crypto || (SHA2 && AES))
       Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
+    if (SHA2)
+      Builder.defineMacro("__ARM_FEATURE_SHA2", "1");
+    if (AES)
+      Builder.defineMacro("__ARM_FEATURE_AES", "1");
     // ACLE 6.5.8 CRC32 Extension
     if (CRC)
       Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
Index: clang/lib/Basic/Targets/AArch64.h
===================================================================
--- clang/lib/Basic/Targets/AArch64.h
+++ clang/lib/Basic/Targets/AArch64.h
@@ -30,6 +30,10 @@
   unsigned FPU;
   bool HasCRC;
   bool HasCrypto;
+  bool HasAES;
+  bool HasSHA2;
+  bool HasSHA3;
+  bool HasSM4;
   bool HasUnaligned;
   bool HasFullFP16;
   bool HasDotProd;
Index: clang/lib/Basic/Targets/AArch64.cpp
===================================================================
--- clang/lib/Basic/Targets/AArch64.cpp
+++ clang/lib/Basic/Targets/AArch64.cpp
@@ -287,9 +287,27 @@
   if (HasCRC)
     Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
 
-  if (HasCrypto)
+  // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained feature
+  // macros for AES, SHA2, SHA3 and SM4
+  if (HasCrypto || (HasAES && HasSHA2))
     Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
 
+  if (HasAES)
+    Builder.defineMacro("__ARM_FEATURE_AES", "1");
+
+  if (HasSHA2)
+    Builder.defineMacro("__ARM_FEATURE_SHA2", "1");
+
+  if (HasSHA3) {
+    Builder.defineMacro("__ARM_FEATURE_SHA3", "1");
+    Builder.defineMacro("__ARM_FEATURE_SHA512", "1");
+  }
+
+  if (HasSM4) {
+    Builder.defineMacro("__ARM_FEATURE_SM3", "1");
+    Builder.defineMacro("__ARM_FEATURE_SM4", "1");
+  }
+
   if (HasUnaligned)
     Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
 
@@ -421,6 +439,11 @@
   FPU = FPUMode;
   HasCRC = false;
   HasCrypto = false;
+  HasAES = false;
+  HasSHA2 = false;
+  HasSHA2 = false;
+  HasSHA3 = false;
+  HasSM4 = false;
   HasUnaligned = true;
   HasFullFP16 = false;
   HasDotProd = false;
@@ -490,6 +513,16 @@
       HasCRC = true;
     if (Feature == "+crypto")
       HasCrypto = true;
+    if (Feature == "+aes")
+      HasAES = true;
+    if (Feature == "+sha2")
+      HasSHA2 = true;
+    if (Feature == "+sha3") {
+      HasSHA2 = true;
+      HasSHA3 = true;
+    }
+    if (Feature == "+sm4")
+      HasSM4 = true;
     if (Feature == "+strict-align")
       HasUnaligned = false;
     if (Feature == "+v8.1a")
Index: clang/include/clang/Basic/arm_neon.td
===================================================================
--- clang/include/clang/Basic/arm_neon.td
+++ clang/include/clang/Basic/arm_neon.td
@@ -1117,12 +1117,14 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 // Crypto
-let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_CRYPTO)" in {
+let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_AES)" in {
 def AESE : SInst<"vaese", "...", "QUc">;
 def AESD : SInst<"vaesd", "...", "QUc">;
 def AESMC : SInst<"vaesmc", "..", "QUc">;
 def AESIMC : SInst<"vaesimc", "..", "QUc">;
+}
 
+let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_SHA2)" in {
 def SHA1H : SInst<"vsha1h", "11", "Ui">;
 def SHA1SU1 : SInst<"vsha1su1", "...", "QUi">;
 def SHA256SU0 : SInst<"vsha256su0", "...", "QUi">;
@@ -1134,7 +1136,9 @@
 def SHA256H : SInst<"vsha256h", "....", "QUi">;
 def SHA256H2 : SInst<"vsha256h2", "....", "QUi">;
 def SHA256SU1 : SInst<"vsha256su1", "....", "QUi">;
+}
 
+let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_SHA3) && defined(__aarch64__)" in {
 def BCAX : SInst<"vbcax", "....", "QUcQUsQUiQUlQcQsQiQl">;
 def EOR3 : SInst<"veor3", "....", "QUcQUsQUiQUlQcQsQiQl">;
 def RAX1 : SInst<"vrax1", "...", "QUl">;
@@ -1142,12 +1146,17 @@
 let isVXAR = 1 in {
 def XAR :  SInst<"vxar", "...I", "QUl">;
 }
+}
+
+let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_SHA512) && defined(__aarch64__)" in {
 
 def SHA512SU0 : SInst<"vsha512su0", "...", "QUl">;
 def SHA512su1 : SInst<"vsha512su1", "....", "QUl">;
 def SHA512H : SInst<"vsha512h", "....", "QUl">;
 def SHA512H2 : SInst<"vsha512h2", "....", "QUl">;
+}
 
+let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_SM3) && defined(__aarch64__)" in {
 def SM3SS1 : SInst<"vsm3ss1", "....", "QUi">;
 def SM3TT1A : SInst<"vsm3tt1a", "....I", "QUi">;
 def SM3TT1B : SInst<"vsm3tt1b", "....I", "QUi">;
@@ -1155,7 +1164,9 @@
 def SM3TT2B : SInst<"vsm3tt2b", "....I", "QUi">;
 def SM3PARTW1 : SInst<"vsm3partw1", "....", "QUi">;
 def SM3PARTW2 : SInst<"vsm3partw2", "....", "QUi">;
+}
 
+let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_SM4) && defined(__aarch64__)" in {
 def SM4E : SInst<"vsm4e", "...", "QUi">;
 def SM4EKEY : SInst<"vsm4ekey", "...", "QUi">;
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to