[clang] 9e7c996 - Additionally set f32 mode with denormal-fp-math

2022-04-29 Thread David Candler via cfe-commits

Author: David Candler
Date: 2022-04-29T15:06:32+01:00
New Revision: 9e7c9967c3fd573ef53b145e24e6a1e6ba930c82

URL: 
https://github.com/llvm/llvm-project/commit/9e7c9967c3fd573ef53b145e24e6a1e6ba930c82
DIFF: 
https://github.com/llvm/llvm-project/commit/9e7c9967c3fd573ef53b145e24e6a1e6ba930c82.diff

LOG: Additionally set f32 mode with denormal-fp-math

When the denormal-fp-math option is used, this should set the
denormal handling mode for all floating point types. However,
currently 32-bit float types can ignore this setting as there is a
variant of the option, denormal-fp-math-f32, specifically for that type
which takes priority when checking the mode based on type and remains
at the default of IEEE. From the description, denormal-fp-math would
be expected to set the mode for floats unless overridden by the f32
variant, and code in the front end only emits the f32 option if it is
different to the general one, so setting just denormal-fp-math should
be valid.

This patch changes the denormal-fp-math option to also set the f32
mode. If denormal-fp-math-f32 is also specified, this is then
overridden as expected, but if it is absent floats will be set to the
mode specified by the former option, rather than remain on the default.

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D122589

Added: 
clang/test/CodeGen/denormalfpmode-f32.c

Modified: 
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Frontend/CompilerInvocation.cpp

Removed: 




diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 0e34d125873b..b5f9e0a13a6f 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2884,6 +2884,7 @@ static void RenderFloatingPointOptions(const ToolChain 
, const Driver ,
 
 case options::OPT_fdenormal_fp_math_EQ:
   DenormalFPMath = llvm::parseDenormalFPAttribute(A->getValue());
+  DenormalFP32Math = DenormalFPMath;
   if (!DenormalFPMath.isValid()) {
 D.Diag(diag::err_drv_invalid_value)
 << A->getAsString(Args) << A->getValue();

diff  --git a/clang/lib/Frontend/CompilerInvocation.cpp 
b/clang/lib/Frontend/CompilerInvocation.cpp
index 66072875765d..b35e3f4fd78a 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1526,7 +1526,8 @@ void CompilerInvocation::GenerateCodeGenArgs(
   if (Opts.FPDenormalMode != llvm::DenormalMode::getIEEE())
 GenerateArg(Args, OPT_fdenormal_fp_math_EQ, Opts.FPDenormalMode.str(), SA);
 
-  if (Opts.FP32DenormalMode != llvm::DenormalMode::getIEEE())
+  if ((Opts.FPDenormalMode != Opts.FP32DenormalMode) ||
+  (Opts.FP32DenormalMode != llvm::DenormalMode::getIEEE()))
 GenerateArg(Args, OPT_fdenormal_fp_math_f32_EQ, 
Opts.FP32DenormalMode.str(),
 SA);
 
@@ -1879,6 +1880,7 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions 
, ArgList ,
   if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_EQ)) {
 StringRef Val = A->getValue();
 Opts.FPDenormalMode = llvm::parseDenormalFPAttribute(Val);
+Opts.FP32DenormalMode = Opts.FPDenormalMode;
 if (!Opts.FPDenormalMode.isValid())
   Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
   }

diff  --git a/clang/test/CodeGen/denormalfpmode-f32.c 
b/clang/test/CodeGen/denormalfpmode-f32.c
new file mode 100644
index ..f89202bcc9ed
--- /dev/null
+++ b/clang/test/CodeGen/denormalfpmode-f32.c
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -S %s -emit-llvm -o - | FileCheck %s 
--check-prefixes=CHECK-ATTR,CHECK-NONE,CHECK-F32-NONE
+// RUN: %clang_cc1 -S -fdenormal-fp-math=ieee %s -emit-llvm -o - | FileCheck 
%s --check-prefixes=CHECK-ATTR,CHECK-NONE,CHECK-F32-NONE
+// RUN: %clang_cc1 -S -fdenormal-fp-math=preserve-sign %s -emit-llvm -o - | 
FileCheck %s --check-prefixes=CHECK-ATTR,CHECK-PS,CHECK-F32-NONE
+// RUN: %clang_cc1 -S -fdenormal-fp-math=positive-zero %s -emit-llvm -o - | 
FileCheck %s --check-prefixes=CHECK-ATTR,CHECK-PZ,CHECK-F32-NONE
+
+// RUN: %clang_cc1 -S -fdenormal-fp-math-f32=ieee %s -emit-llvm -o - | 
FileCheck %s --check-prefixes=CHECK-ATTR,CHECK-NONE,CHECK-F32-NONE
+// RUN: %clang_cc1 -S -fdenormal-fp-math=ieee -fdenormal-fp-math-f32=ieee %s 
-emit-llvm -o - | FileCheck %s 
--check-prefixes=CHECK-ATTR,CHECK-NONE,CHECK-F32-NONE
+// RUN: %clang_cc1 -S -fdenormal-fp-math=preserve-sign 
-fdenormal-fp-math-f32=ieee %s -emit-llvm -o - | FileCheck %s 
--check-prefixes=CHECK-ATTR,CHECK-PS,CHECK-F32-IEEE
+// RUN: %clang_cc1 -S -fdenormal-fp-math=positive-zero 
-fdenormal-fp-math-f32=ieee %s -emit-llvm -o - | FileCheck %s 
--check-prefixes=CHECK-ATTR,CHECK-PZ,CHECK-F32-IEEE
+
+// RUN: %clang_cc1 -S -fdenormal-fp-math-f32=preserve-sign %s -emit-llvm -o - 
| FileCheck %s --check-prefixes=CHECK-ATTR,CHECK-NONE,CHECK-F32-PS
+// RUN: %clang_cc1 -S -fdenormal-fp-math=ieee 

[clang] 3d59f9d - [ARM][AArch64] Correct __ARM_FEATURE_CRYPTO macro and crypto feature

2021-05-14 Thread David Candler via cfe-commits

Author: David Candler
Date: 2021-05-14T14:19:46+01:00
New Revision: 3d59f9d22440645ca0237dfc5d91ca09f749174b

URL: 
https://github.com/llvm/llvm-project/commit/3d59f9d22440645ca0237dfc5d91ca09f749174b
DIFF: 
https://github.com/llvm/llvm-project/commit/3d59f9d22440645ca0237dfc5d91ca09f749174b.diff

LOG: [ARM][AArch64] Correct __ARM_FEATURE_CRYPTO macro and crypto feature

This patch contains a couple of minor corrections to my previous
crypto patch:

Since both AArch32 and AArch64 are now correctly setting the aes and
sha2 features individually, it is not necessary to continue to check
the crypto feature when defining feature macros.

In the AArch32 driver, the feature vector is only modified when the
crypto feature is actually in the vector. If crypto is not present,
there is no need to split it and explicitly define crypto/sha2/aes.

Reviewed By: lenary

Differential Revision: https://reviews.llvm.org/D102406

Added: 


Modified: 
clang/lib/Basic/Targets/AArch64.cpp
clang/lib/Basic/Targets/ARM.cpp
clang/lib/Driver/ToolChains/Arch/ARM.cpp

Removed: 




diff  --git a/clang/lib/Basic/Targets/AArch64.cpp 
b/clang/lib/Basic/Targets/AArch64.cpp
index d26ae943b2e8a..82273a5e97aef 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -289,7 +289,7 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions 
,
 
   // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained feature
   // macros for AES, SHA2, SHA3 and SM4
-  if (HasCrypto || (HasAES && HasSHA2))
+  if (HasAES && HasSHA2)
 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
 
   if (HasAES)

diff  --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp
index 748a59525ef20..12439fcbeff96 100644
--- a/clang/lib/Basic/Targets/ARM.cpp
+++ b/clang/lib/Basic/Targets/ARM.cpp
@@ -649,7 +649,7 @@ void ARMTargetInfo::getTargetDefines(const LangOptions 
,
 // ACLE 6.5.7 Crypto Extension
 // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained
 // feature macros for AES and SHA2
-if (Crypto || (SHA2 && AES))
+if (SHA2 && AES)
   Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
 if (SHA2)
   Builder.defineMacro("__ARM_FEATURE_SHA2", "1");

diff  --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp 
b/clang/lib/Driver/ToolChains/Arch/ARM.cpp
index 061eaf7924dbe..16d72e5367f58 100644
--- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp
@@ -636,6 +636,10 @@ void arm::getARMTargetFeatures(const Driver , const 
llvm::Triple ,
   // FIXME: this needs reimplementation after the TargetParser rewrite
   bool HasSHA2 = false;
   bool HasAES = false;
+  const auto ItCrypto =
+  llvm::find_if(llvm::reverse(Features), [](const StringRef F) {
+return F.contains("crypto");
+  });
   const auto ItSHA2 =
   llvm::find_if(llvm::reverse(Features), [](const StringRef F) {
 return F.contains("crypto") || F.contains("sha2");
@@ -650,7 +654,7 @@ void arm::getARMTargetFeatures(const Driver , const 
llvm::Triple ,
 HasSHA2 = ItSHA2->take_front() == "+";
   if (FoundAES)
 HasAES = ItAES->take_front() == "+";
-  if (FoundSHA2 || FoundAES) {
+  if (ItCrypto != Features.rend()) {
 if (HasSHA2 && HasAES)
   Features.push_back("+crypto");
 else



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] b8baa2a - [ARM][AArch64] Require appropriate features for crypto algorithms

2021-04-28 Thread David Candler via cfe-commits

Author: David Candler
Date: 2021-04-28T16:26:18+01:00
New Revision: b8baa2a9132498ea286dbb0d03f005760ecc6fdb

URL: 
https://github.com/llvm/llvm-project/commit/b8baa2a9132498ea286dbb0d03f005760ecc6fdb
DIFF: 
https://github.com/llvm/llvm-project/commit/b8baa2a9132498ea286dbb0d03f005760ecc6fdb.diff

LOG: [ARM][AArch64] Require appropriate features for crypto algorithms

This patch changes the AArch32 crypto instructions (sha2 and aes) to
require the specific sha2 or aes features. These features have
already been implemented and can be controlled through the command
line, but do not have the expected result (i.e. `+noaes` will not
disable aes instructions). The crypto feature retains its existing
meaning of both sha2 and aes.

Several small changes are included due to the knock-on effect this has:

- The AArch32 driver has been modified to ensure sha2/aes is correctly
  set based on arch/cpu/fpu selection and feature ordering.
- Crypto extensions are permitted for AArch32 v8-R profile, but not
  enabled by default.
- ACLE feature macros have been updated with the fine grained crypto
  algorithms. These are also used by AArch64.
- Various tests updated due to the change in feature lists and macros.

Reviewed By: lenary

Differential Revision: https://reviews.llvm.org/D99079

Added: 
llvm/test/MC/ARM/directive-arch_extension-aes-sha2.s

Modified: 
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-crypto.s
llvm/test/MC/ARM/neon-crypto.s

Removed: 




diff  --git a/clang/include/clang/Basic/arm_neon.td 
b/clang/include/clang/Basic/arm_neon.td
index 6e3ed6ebbd39f..0d97f0a1c2dc5 100644
--- a/clang/include/clang/Basic/arm_neon.td
+++ b/clang/include/clang/Basic/arm_neon.td
@@ -1117,12 +1117,14 @@ def VEXT_A64 : WInst<"vext", "...I", "dQdPlQPl">;
 
 

 // 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 SHA1SU0 : SInst<"vsha1su0", "", "QUi">;
 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 @@ def RAX1 : SInst<"vrax1", "...", "QUl">;
 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 SM3TT2A : SInst<"vsm3tt2a", "I", "QUi">;
 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__)" 

[clang] 92aa0c2 - [cfi] Add flag to always generate .debug_frame

2019-10-31 Thread David Candler via cfe-commits

Author: David Candler
Date: 2019-10-31T09:48:30Z
New Revision: 92aa0c2dbcb723d102c508f6e7559330b637f912

URL: 
https://github.com/llvm/llvm-project/commit/92aa0c2dbcb723d102c508f6e7559330b637f912
DIFF: 
https://github.com/llvm/llvm-project/commit/92aa0c2dbcb723d102c508f6e7559330b637f912.diff

LOG: [cfi] Add flag to always generate .debug_frame

This adds a flag to LLVM and clang to always generate a .debug_frame
section, even if other debug information is not being generated. In
situations where .eh_frame would normally be emitted, both .debug_frame
and .eh_frame will be used.

Differential Revision: https://reviews.llvm.org/D67216

Added: 
clang/test/Driver/fforce-dwarf-frame.c
llvm/test/CodeGen/ARM/dwarf-frame.ll

Modified: 
clang/include/clang/Basic/CodeGenOptions.def
clang/include/clang/Driver/Options.td
clang/lib/CodeGen/BackendUtil.cpp
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Frontend/CompilerInvocation.cpp
llvm/include/llvm/CodeGen/CommandFlags.inc
llvm/include/llvm/CodeGen/MachineFunction.h
llvm/include/llvm/Target/TargetOptions.h
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
llvm/lib/CodeGen/CFIInstrInserter.cpp
llvm/lib/CodeGen/MachineFunction.cpp
llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
llvm/lib/Target/ARC/ARCRegisterInfo.cpp
llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
llvm/lib/Target/X86/X86FrameLowering.cpp
llvm/lib/Target/X86/X86InstrInfo.cpp
llvm/lib/Target/XCore/XCoreRegisterInfo.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/CodeGenOptions.def 
b/clang/include/clang/Basic/CodeGenOptions.def
index f8d94e352f28..0a47869af61b 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -97,6 +97,8 @@ CODEGENOPT(CFProtectionBranch , 1, 0) ///< if -fcf-protection 
is
 CODEGENOPT(XRayInstrumentFunctions , 1, 0) ///< Set when -fxray-instrument is
///< enabled.
 CODEGENOPT(StackSizeSection  , 1, 0) ///< Set when -fstack-size-section is 
enabled.
+CODEGENOPT(ForceDwarfFrameSection , 1, 0) ///< Set when -fforce-dwarf-frame is
+  ///< enabled.
 
 ///< Set when -fxray-always-emit-customevents is enabled.
 CODEGENOPT(XRayAlwaysEmitCustomEvents , 1, 0)

diff  --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 2401a31ceb9a..07c27ebcefee 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1950,6 +1950,10 @@ def fdebug_prefix_map_EQ
   : Joined<["-"], "fdebug-prefix-map=">, Group,
 Flags<[CC1Option,CC1AsOption]>,
 HelpText<"remap file source paths in debug info">;
+def fforce_dwarf_frame : Flag<["-"], "fforce-dwarf-frame">, Group, 
Flags<[CC1Option]>,
+HelpText<"Always emit a debug frame section">;
+def fno_force_dwarf_frame : Flag<["-"], "fno-force-dwarf-frame">, 
Group, Flags<[CC1Option]>,
+HelpText<"Don't always emit a debug frame section">;
 def g_Flag : Flag<["-"], "g">, Group,
   HelpText<"Generate source-level debug information">;
 def gline_tables_only : Flag<["-"], "gline-tables-only">, Group,

diff  --git a/clang/lib/CodeGen/BackendUtil.cpp 
b/clang/lib/CodeGen/BackendUtil.cpp
index 75a54d8f3c8a..c15dc0be0b15 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -485,6 +485,7 @@ static void initTargetOptions(llvm::TargetOptions ,
   Options.EmitStackSizeSection = CodeGenOpts.StackSizeSection;
   Options.EmitAddrsig = CodeGenOpts.Addrsig;
   Options.EnableDebugEntryValues = CodeGenOpts.EnableDebugEntryValues;
+  Options.ForceDwarfFrameSection = CodeGenOpts.ForceDwarfFrameSection;
 
   Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile;
   Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;

diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index c60dc76ae1bf..81e01aee1da9 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3339,6 +3339,10 @@ static void RenderDebugOptions(const ToolChain , 
const Driver ,
 CmdArgs.push_back("-generate-arange-section");
   }
 
+  if (Args.hasFlag(options::OPT_fforce_dwarf_frame,
+   options::OPT_fno_force_dwarf_frame, false))
+CmdArgs.push_back("-fforce-dwarf-frame");
+
   if (Args.hasFlag(options::OPT_fdebug_types_section,
options::OPT_fno_debug_types_section, false)) {
 if (!T.isOSBinFormatELF()) {

diff  --git a/clang/lib/Frontend/CompilerInvocation.cpp 
b/clang/lib/Frontend/CompilerInvocation.cpp
index f197a67e7a38..0775d1021c54 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -769,6 +769,9 @@ 

r371079 - [ARM] Add support for the s,j,x,N,O inline asm constraints

2019-09-05 Thread David Candler via cfe-commits
Author: dcandler
Date: Thu Sep  5 08:17:25 2019
New Revision: 371079

URL: http://llvm.org/viewvc/llvm-project?rev=371079=rev
Log:
[ARM] Add support for the s,j,x,N,O inline asm constraints

A number of inline assembly constraints are currently supported by LLVM, but 
rejected as invalid by Clang:

Target independent constraints:

s: An integer constant, but allowing only relocatable values

ARM specific constraints:

j: An immediate integer between 0 and 65535 (valid for MOVW)
x: A 32, 64, or 128-bit floating-point/SIMD register: s0-s15, d0-d7, or q0-q3
N: An immediate integer between 0 and 31 (Thumb1 only)
O: An immediate integer which is a multiple of 4 between -508 and 508. (Thumb1 
only)

This patch adds support to Clang for the missing constraints along with some 
checks to ensure that the constraints are used with the correct target and 
Thumb mode, and that immediates are within valid ranges (at least where 
possible). The constraints are already implemented in LLVM, but just a couple 
of minor corrections to checks (V8M Baseline includes MOVW so should work with 
'j', 'N' and 'O' shouldn't be valid in Thumb2) so that Clang and LLVM are in 
line with each other and the documentation.

Differential Revision: https://reviews.llvm.org/D65863

Change-Id: I18076619e319bac35fbb60f590c069145c9d9a0a

Added:
cfe/trunk/test/Sema/arm_inline_asm_constraints.c
Modified:
cfe/trunk/lib/Basic/Targets/ARM.cpp

Modified: cfe/trunk/lib/Basic/Targets/ARM.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets/ARM.cpp?rev=371079=371078=371079=diff
==
--- cfe/trunk/lib/Basic/Targets/ARM.cpp (original)
+++ cfe/trunk/lib/Basic/Targets/ARM.cpp Thu Sep  5 08:17:25 2019
@@ -885,19 +885,102 @@ bool ARMTargetInfo::validateAsmConstrain
   switch (*Name) {
   default:
 break;
-  case 'l': // r0-r7
-  case 'h': // r8-r15
-  case 't': // VFP Floating point register single precision
-  case 'w': // VFP Floating point register double precision
+  case 'l': // r0-r7 if thumb, r0-r15 if ARM
 Info.setAllowsRegister();
 return true;
+  case 'h': // r8-r15, thumb only
+if (isThumb()) {
+  Info.setAllowsRegister();
+  return true;
+}
+break;
+  case 's': // An integer constant, but allowing only relocatable values.
+return true;
+  case 't': // s0-s31, d0-d31, or q0-q15
+  case 'w': // s0-s15, d0-d7, or q0-q3
+  case 'x': // s0-s31, d0-d15, or q0-q7
+Info.setAllowsRegister();
+return true;
+  case 'j': // An immediate integer between 0 and 65535 (valid for MOVW)
+// only available in ARMv6T2 and above
+if (CPUAttr.equals("6T2") || ArchVersion >= 7) {
+  Info.setRequiresImmediate(0, 65535);
+  return true;
+}
+break;
   case 'I':
+if (isThumb()) {
+  if (!supportsThumb2())
+Info.setRequiresImmediate(0, 255);
+  else
+// FIXME: should check if immediate value would be valid for a Thumb2
+// data-processing instruction
+Info.setRequiresImmediate();
+} else
+  // FIXME: should check if immediate value would be valid for an ARM
+  // data-processing instruction
+  Info.setRequiresImmediate();
+return true;
   case 'J':
+if (isThumb() && !supportsThumb2())
+  Info.setRequiresImmediate(-255, -1);
+else
+  Info.setRequiresImmediate(-4095, 4095);
+return true;
   case 'K':
+if (isThumb()) {
+  if (!supportsThumb2())
+// FIXME: should check if immediate value can be obtained from shifting
+// a value between 0 and 255 left by any amount
+Info.setRequiresImmediate();
+  else
+// FIXME: should check if immediate value would be valid for a Thumb2
+// data-processing instruction when inverted
+Info.setRequiresImmediate();
+} else
+  // FIXME: should check if immediate value would be valid for an ARM
+  // data-processing instruction when inverted
+  Info.setRequiresImmediate();
+return true;
   case 'L':
+if (isThumb()) {
+  if (!supportsThumb2())
+Info.setRequiresImmediate(-7, 7);
+  else
+// FIXME: should check if immediate value would be valid for a Thumb2
+// data-processing instruction when negated
+Info.setRequiresImmediate();
+} else
+  // FIXME: should check if immediate value  would be valid for an ARM
+  // data-processing instruction when negated
+  Info.setRequiresImmediate();
+return true;
   case 'M':
-// FIXME
+if (isThumb() && !supportsThumb2())
+  // FIXME: should check if immediate value is a multiple of 4 between 0 
and
+  // 1020
+  Info.setRequiresImmediate();
+else
+  // FIXME: should check if immediate value is a power of two or a integer
+  // between 0 and 32
+  Info.setRequiresImmediate();
 return true;
+  case 'N':
+// Thumb1 only
+if (isThumb() && !supportsThumb2()) {
+