diff options
| author | Sanne Wouda <sanne.wouda@arm.com> | 2017-03-28 10:02:56 +0000 | 
|---|---|---|
| committer | Sanne Wouda <sanne.wouda@arm.com> | 2017-03-28 10:02:56 +0000 | 
| commit | d4658ee63400efeb464750062530e7f24b344f23 (patch) | |
| tree | cbc46cd8de49b3a85f14ff4dcac342b520516c19 | |
| parent | f580fce2c34461433e404b5dacad87a483d1164e (diff) | |
| download | bcm5719-llvm-d4658ee63400efeb464750062530e7f24b344f23.tar.gz bcm5719-llvm-d4658ee63400efeb464750062530e7f24b344f23.zip  | |
[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
llvm-svn: 298908
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64.td | 8 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstrFormats.td | 23 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstrInfo.td | 5 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64Subtarget.h | 4 | ||||
| -rw-r--r-- | llvm/test/MC/AArch64/alias-addsubimm.s | 21 | ||||
| -rw-r--r-- | llvm/test/MC/AArch64/alias-logicalimm.s | 9 | 
6 files changed, 60 insertions, 10 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td index a6dbb2a1c39..09897104f32 100644 --- a/llvm/lib/Target/AArch64/AArch64.td +++ b/llvm/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/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td index 6da730618e0..16be4432b16 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -39,6 +39,9 @@ class AArch64Inst<Format f, string cstr> : Instruction {    let Constraints = cstr;  } +class InstSubst<string Asm, dag Result, bit EmitPriority = 0> +  : InstAlias<Asm, Result, EmitPriority>, Requires<[UseNegativeImmediates]>; +  // Pseudo instructions (don't have encoding information)  class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = "">      : AArch64Inst<PseudoFrm, cstr> { @@ -1798,10 +1801,10 @@ multiclass AddSub<bit isSub, string mnemonic, string alias,    }    // add Rd, Rb, -imm -> sub Rd, Rn, imm -  def : InstAlias<alias#"\t$Rd, $Rn, $imm", +  def : InstSubst<alias#"\t$Rd, $Rn, $imm",                    (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn,                        addsub_shifted_imm32_neg:$imm), 0>; -  def : InstAlias<alias#"\t$Rd, $Rn, $imm", +  def : InstSubst<alias#"\t$Rd, $Rn, $imm",                    (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn,                         addsub_shifted_imm64_neg:$imm), 0>; @@ -1873,10 +1876,10 @@ multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp,    } // Defs = [NZCV]    // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm -  def : InstAlias<alias#"\t$Rd, $Rn, $imm", +  def : InstSubst<alias#"\t$Rd, $Rn, $imm",                    (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn,                        addsub_shifted_imm32_neg:$imm), 0>; -  def : InstAlias<alias#"\t$Rd, $Rn, $imm", +  def : InstSubst<alias#"\t$Rd, $Rn, $imm",                    (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn,                         addsub_shifted_imm64_neg:$imm), 0>; @@ -1897,9 +1900,9 @@ multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp,                    XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>;    // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm -  def : InstAlias<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") +  def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")                    WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>; -  def : InstAlias<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") +  def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")                    XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>;    // Compare shorthands @@ -2114,10 +2117,10 @@ multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,      let Inst{31} = 1;    } -  def : InstAlias<Alias # "\t$Rd, $Rn, $imm", +  def : InstSubst<Alias # "\t$Rd, $Rn, $imm",                    (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,                        logical_imm32_not:$imm), 0>; -  def : InstAlias<Alias # "\t$Rd, $Rn, $imm", +  def : InstSubst<Alias # "\t$Rd, $Rn, $imm",                    (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn,                         logical_imm64_not:$imm), 0>;  } @@ -2136,10 +2139,10 @@ multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode,    }    } // end Defs = [NZCV] -  def : InstAlias<Alias # "\t$Rd, $Rn, $imm", +  def : InstSubst<Alias # "\t$Rd, $Rn, $imm",                    (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,                        logical_imm32_not:$imm), 0>; -  def : InstAlias<Alias # "\t$Rd, $Rn, $imm", +  def : InstSubst<Alias # "\t$Rd, $Rn, $imm",                    (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,                         logical_imm64_not:$imm), 0>;  } diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 6a6dba34606..4449412532f 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/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/llvm/lib/Target/AArch64/AArch64Subtarget.h b/llvm/lib/Target/AArch64/AArch64Subtarget.h index 0a42ba5060f..10377cbbb16 100644 --- a/llvm/lib/Target/AArch64/AArch64Subtarget.h +++ b/llvm/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/llvm/test/MC/AArch64/alias-addsubimm.s b/llvm/test/MC/AArch64/alias-addsubimm.s index 75e0a185572..5c1c4799828 100644 --- a/llvm/test/MC/AArch64/alias-addsubimm.s +++ b/llvm/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/llvm/test/MC/AArch64/alias-logicalimm.s b/llvm/test/MC/AArch64/alias-logicalimm.s index 28ec40beac4..427a06d6514 100644 --- a/llvm/test/MC/AArch64/alias-logicalimm.s +++ b/llvm/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  | 

