From: Sanne Wouda Date: Tue, 28 Mar 2017 10:02:56 +0000 (+0000) Subject: [AArch64] [Assembler] option to disable negative immediate conversions X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c05e81481a21b94385a593679ad537a837cdab4b;p=llvm [AArch64] [Assembler] option to disable negative immediate conversions Summary: Similar to the ARM target in https://reviews.llvm.org/rL298380, this patch adds identical infrastructure for disabling negative immediate conversions, and converts the existing aliases to the new infrastucture. Reviewers: rengolin, javed.absar, olista01, SjoerdMeijer, samparker Reviewed By: samparker Subscribers: samparker, aemerson, llvm-commits Differential Revision: https://reviews.llvm.org/D31243 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298908 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/AArch64/AArch64.td b/lib/Target/AArch64/AArch64.td index a6dbb2a1c39..09897104f32 100644 --- a/lib/Target/AArch64/AArch64.td +++ b/lib/Target/AArch64/AArch64.td @@ -118,6 +118,14 @@ def FeatureDisableLatencySchedHeuristic : SubtargetFeature< def FeatureUseRSqrt : SubtargetFeature< "use-reciprocal-square-root", "UseRSqrt", "true", "Use the reciprocal square root approximation">; + +def FeatureNoNegativeImmediates : SubtargetFeature<"no-neg-immediates", + "NegativeImmediates", "false", + "Convert immediates and instructions " + "to their negated or complemented " + "equivalent when the immediate does " + "not fit in the encoding.">; + //===----------------------------------------------------------------------===// // Architectures. // diff --git a/lib/Target/AArch64/AArch64InstrFormats.td b/lib/Target/AArch64/AArch64InstrFormats.td index 6da730618e0..16be4432b16 100644 --- a/lib/Target/AArch64/AArch64InstrFormats.td +++ b/lib/Target/AArch64/AArch64InstrFormats.td @@ -39,6 +39,9 @@ class AArch64Inst : Instruction { let Constraints = cstr; } +class InstSubst + : InstAlias, Requires<[UseNegativeImmediates]>; + // Pseudo instructions (don't have encoding information) class Pseudo pattern, string cstr = ""> : AArch64Inst { @@ -1798,10 +1801,10 @@ multiclass AddSub sub Rd, Rn, imm - def : InstAlias(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn, addsub_shifted_imm32_neg:$imm), 0>; - def : InstAlias(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn, addsub_shifted_imm64_neg:$imm), 0>; @@ -1873,10 +1876,10 @@ multiclass AddSubS subs Rd, Rn, imm - def : InstAlias(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn, addsub_shifted_imm32_neg:$imm), 0>; - def : InstAlias(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn, addsub_shifted_imm64_neg:$imm), 0>; @@ -1897,9 +1900,9 @@ multiclass AddSubS; // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm - def : InstAlias(NAME#"Wri") + def : InstSubst(NAME#"Wri") WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>; - def : InstAlias(NAME#"Xri") + def : InstSubst(NAME#"Xri") XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>; // Compare shorthands @@ -2114,10 +2117,10 @@ multiclass LogicalImm opc, string mnemonic, SDNode OpNode, let Inst{31} = 1; } - def : InstAlias(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn, logical_imm32_not:$imm), 0>; - def : InstAlias(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn, logical_imm64_not:$imm), 0>; } @@ -2136,10 +2139,10 @@ multiclass LogicalImmS opc, string mnemonic, SDNode OpNode, } } // end Defs = [NZCV] - def : InstAlias(NAME # "Wri") GPR32:$Rd, GPR32:$Rn, logical_imm32_not:$imm), 0>; - def : InstAlias(NAME # "Xri") GPR64:$Rd, GPR64:$Rn, logical_imm64_not:$imm), 0>; } diff --git a/lib/Target/AArch64/AArch64InstrInfo.td b/lib/Target/AArch64/AArch64InstrInfo.td index 6a6dba34606..4449412532f 100644 --- a/lib/Target/AArch64/AArch64InstrInfo.td +++ b/lib/Target/AArch64/AArch64InstrInfo.td @@ -43,6 +43,11 @@ def IsBE : Predicate<"!Subtarget->isLittleEndian()">; def UseAlternateSExtLoadCVTF32 : Predicate<"Subtarget->useAlternateSExtLoadCVTF32Pattern()">; +def UseNegativeImmediates + : Predicate<"false">, AssemblerPredicate<"!FeatureNoNegativeImmediates", + "NegativeImmediates">; + + //===----------------------------------------------------------------------===// // AArch64-specific DAG Nodes. // diff --git a/lib/Target/AArch64/AArch64Subtarget.h b/lib/Target/AArch64/AArch64Subtarget.h index 0a42ba5060f..10377cbbb16 100644 --- a/lib/Target/AArch64/AArch64Subtarget.h +++ b/lib/Target/AArch64/AArch64Subtarget.h @@ -78,6 +78,10 @@ protected: // StrictAlign - Disallow unaligned memory accesses. bool StrictAlign = false; + + // NegativeImmediates - transform instructions with negative immediates + bool NegativeImmediates = true; + bool UseAA = false; bool PredictableSelectIsExpensive = false; bool BalanceFPOps = false; diff --git a/test/MC/AArch64/alias-addsubimm.s b/test/MC/AArch64/alias-addsubimm.s index 75e0a185572..5c1c4799828 100644 --- a/test/MC/AArch64/alias-addsubimm.s +++ b/test/MC/AArch64/alias-addsubimm.s @@ -1,19 +1,24 @@ // RUN: llvm-mc -triple=aarch64-none-linux-gnu < %s | FileCheck %s +// RUN: not llvm-mc -mattr=+no-neg-immediates -triple=aarch64-none-linux-gnu < %s 2>&1 | FileCheck %s --check-prefix=CHECK-NO-NEG-IMM // CHECK: sub w0, w2, #2, lsl #12 // CHECK: sub w0, w2, #2, lsl #12 +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates sub w0, w2, #2, lsl 12 add w0, w2, #-2, lsl 12 // CHECK: sub x1, x3, #2, lsl #12 // CHECK: sub x1, x3, #2, lsl #12 +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates sub x1, x3, #2, lsl 12 add x1, x3, #-2, lsl 12 // CHECK: sub x1, x3, #4 // CHECK: sub x1, x3, #4 +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates sub x1, x3, #4 add x1, x3, #-4 // CHECK: sub x1, x3, #4095 // CHECK: sub x1, x3, #4095 +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates sub x1, x3, #4095, lsl 0 add x1, x3, #-4095, lsl 0 // CHECK: sub x3, x4, #0 @@ -21,18 +26,22 @@ // CHECK: add w0, w2, #2, lsl #12 // CHECK: add w0, w2, #2, lsl #12 +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates add w0, w2, #2, lsl 12 sub w0, w2, #-2, lsl 12 // CHECK: add x1, x3, #2, lsl #12 // CHECK: add x1, x3, #2, lsl #12 +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates add x1, x3, #2, lsl 12 sub x1, x3, #-2, lsl 12 // CHECK: add x1, x3, #4 // CHECK: add x1, x3, #4 +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates add x1, x3, #4 sub x1, x3, #-4 // CHECK: add x1, x3, #4095 // CHECK: add x1, x3, #4095 +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates add x1, x3, #4095, lsl 0 sub x1, x3, #-4095, lsl 0 // CHECK: add x2, x5, #0 @@ -40,18 +49,22 @@ // CHECK: subs w0, w2, #2, lsl #12 // CHECK: subs w0, w2, #2, lsl #12 +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates subs w0, w2, #2, lsl 12 adds w0, w2, #-2, lsl 12 // CHECK: subs x1, x3, #2, lsl #12 // CHECK: subs x1, x3, #2, lsl #12 +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates subs x1, x3, #2, lsl 12 adds x1, x3, #-2, lsl 12 // CHECK: subs x1, x3, #4 // CHECK: subs x1, x3, #4 +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates subs x1, x3, #4 adds x1, x3, #-4 // CHECK: subs x1, x3, #4095 // CHECK: subs x1, x3, #4095 +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates subs x1, x3, #4095, lsl 0 adds x1, x3, #-4095, lsl 0 // CHECK: subs x3, x4, #0 @@ -59,18 +72,22 @@ // CHECK: adds w0, w2, #2, lsl #12 // CHECK: adds w0, w2, #2, lsl #12 +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates adds w0, w2, #2, lsl 12 subs w0, w2, #-2, lsl 12 // CHECK: adds x1, x3, #2, lsl #12 // CHECK: adds x1, x3, #2, lsl #12 +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates adds x1, x3, #2, lsl 12 subs x1, x3, #-2, lsl 12 // CHECK: adds x1, x3, #4 // CHECK: adds x1, x3, #4 +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates adds x1, x3, #4 subs x1, x3, #-4 // CHECK: adds x1, x3, #4095 // CHECK: adds x1, x3, #4095 +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates adds x1, x3, #4095, lsl 0 subs x1, x3, #-4095, lsl 0 // CHECK: adds x2, x5, #0 @@ -78,17 +95,21 @@ // CHECK: {{adds xzr,|cmn}} x5, #5 // CHECK: {{adds xzr,|cmn}} x5, #5 +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates cmn x5, #5 cmp x5, #-5 // CHECK: {{subs xzr,|cmp}} x6, #4095 // CHECK: {{subs xzr,|cmp}} x6, #4095 +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates cmp x6, #4095 cmn x6, #-4095 // CHECK: {{adds wzr,|cmn}} w7, #5 // CHECK: {{adds wzr,|cmn}} w7, #5 +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates cmn w7, #5 cmp w7, #-5 // CHECK: {{subs wzr,|cmp}} w8, #4095 // CHECK: {{subs wzr,|cmp}} w8, #4095 +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates cmp w8, #4095 cmn w8, #-4095 diff --git a/test/MC/AArch64/alias-logicalimm.s b/test/MC/AArch64/alias-logicalimm.s index 28ec40beac4..427a06d6514 100644 --- a/test/MC/AArch64/alias-logicalimm.s +++ b/test/MC/AArch64/alias-logicalimm.s @@ -1,41 +1,50 @@ // RUN: llvm-mc -triple=aarch64-none-linux-gnu < %s | FileCheck %s +// RUN: not llvm-mc -mattr=+no-neg-immediates -triple=aarch64-none-linux-gnu < %s 2>&1 | FileCheck %s --check-prefix=CHECK-NO-NEG-IMM // CHECK: and x0, x1, #0xfffffffffffffffd // CHECK: and x0, x1, #0xfffffffffffffffd +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates and x0, x1, #~2 bic x0, x1, #2 // CHECK: and w0, w1, #0xfffffffd // CHECK: and w0, w1, #0xfffffffd +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates and w0, w1, #~2 bic w0, w1, #2 // CHECK: ands x0, x1, #0xfffffffffffffffd // CHECK: ands x0, x1, #0xfffffffffffffffd +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates ands x0, x1, #~2 bics x0, x1, #2 // CHECK: ands w0, w1, #0xfffffffd // CHECK: ands w0, w1, #0xfffffffd +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates ands w0, w1, #~2 bics w0, w1, #2 // CHECK: orr x0, x1, #0xfffffffffffffffd // CHECK: orr x0, x1, #0xfffffffffffffffd +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates orr x0, x1, #~2 orn x0, x1, #2 // CHECK: orr w2, w1, #0xfffffffc // CHECK: orr w2, w1, #0xfffffffc +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates orr w2, w1, #~3 orn w2, w1, #3 // CHECK: eor x0, x1, #0xfffffffffffffffd // CHECK: eor x0, x1, #0xfffffffffffffffd +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates eor x0, x1, #~2 eon x0, x1, #2 // CHECK: eor w2, w1, #0xfffffffc // CHECK: eor w2, w1, #0xfffffffc +// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates eor w2, w1, #~3 eon w2, w1, #3