summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorDavid Green <david.green@arm.com>2018-08-30 11:55:16 +0000
committerDavid Green <david.green@arm.com>2018-08-30 11:55:16 +0000
commit1f203bcd750408d2df42adebe54ec276d81f5f0d (patch)
tree01c6ebc8e56149a2957062ea841eb35f2a02c570 /llvm/lib/Target
parent38bdac5db854d298013388cd6887f49f56d10ffe (diff)
downloadbcm5719-llvm-1f203bcd750408d2df42adebe54ec276d81f5f0d.tar.gz
bcm5719-llvm-1f203bcd750408d2df42adebe54ec276d81f5f0d.zip
[AArch64] Optimise load(adr address) to ldr address
Providing that the load is known to be 4 byte aligned, we can optimise a ldr(adr address) to just ldr address. Differential Revision: https://reviews.llvm.org/D51030 llvm-svn: 341058
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstrFormats.td6
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstrInfo.td35
2 files changed, 32 insertions, 9 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index 123cddd53ba..4e935bdc1ad 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -2853,10 +2853,10 @@ def am_ldrlit : Operand<iPTR> {
let OperandType = "OPERAND_PCREL";
}
-let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
-class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm>
+let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in
+class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat>
: I<(outs regtype:$Rt), (ins am_ldrlit:$label),
- asm, "\t$Rt, $label", "", []>,
+ asm, "\t$Rt, $label", "", pat>,
Sched<[WriteLD]> {
bits<5> Rt;
bits<19> label;
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index f1ec76bdf7c..753c91b01c5 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -1891,14 +1891,37 @@ def : InstAlias<"prfm $Rt, [$Rn]", (PRFMui prfop:$Rt, GPR64sp:$Rn, 0)>;
//---
// (literal)
-def LDRWl : LoadLiteral<0b00, 0, GPR32z, "ldr">;
-def LDRXl : LoadLiteral<0b01, 0, GPR64z, "ldr">;
-def LDRSl : LoadLiteral<0b00, 1, FPR32Op, "ldr">;
-def LDRDl : LoadLiteral<0b01, 1, FPR64Op, "ldr">;
-def LDRQl : LoadLiteral<0b10, 1, FPR128Op, "ldr">;
+
+def alignedglobal : PatLeaf<(iPTR iPTR:$label), [{
+ if (auto *G = dyn_cast<GlobalAddressSDNode>(N)) {
+ const DataLayout &DL = MF->getDataLayout();
+ unsigned Align = G->getGlobal()->getPointerAlignment(DL);
+ return Align >= 4 && G->getOffset() % 4 == 0;
+ }
+ if (auto *C = dyn_cast<ConstantPoolSDNode>(N))
+ return C->getAlignment() >= 4 && C->getOffset() % 4 == 0;
+ return false;
+}]>;
+
+def LDRWl : LoadLiteral<0b00, 0, GPR32z, "ldr",
+ [(set GPR32z:$Rt, (load (AArch64adr alignedglobal:$label)))]>;
+def LDRXl : LoadLiteral<0b01, 0, GPR64z, "ldr",
+ [(set GPR64z:$Rt, (load (AArch64adr alignedglobal:$label)))]>;
+def LDRSl : LoadLiteral<0b00, 1, FPR32Op, "ldr",
+ [(set (f32 FPR32Op:$Rt), (load (AArch64adr alignedglobal:$label)))]>;
+def LDRDl : LoadLiteral<0b01, 1, FPR64Op, "ldr",
+ [(set (f64 FPR64Op:$Rt), (load (AArch64adr alignedglobal:$label)))]>;
+def LDRQl : LoadLiteral<0b10, 1, FPR128Op, "ldr",
+ [(set (f128 FPR128Op:$Rt), (load (AArch64adr alignedglobal:$label)))]>;
// load sign-extended word
-def LDRSWl : LoadLiteral<0b10, 0, GPR64z, "ldrsw">;
+def LDRSWl : LoadLiteral<0b10, 0, GPR64z, "ldrsw",
+ [(set GPR64z:$Rt, (sextloadi32 (AArch64adr alignedglobal:$label)))]>;
+
+let AddedComplexity = 20 in {
+def : Pat<(i64 (zextloadi32 (AArch64adr alignedglobal:$label))),
+ (SUBREG_TO_REG (i64 0), (LDRWl $label), sub_32)>;
+}
// prefetch
def PRFMl : PrefetchLiteral<0b11, 0, "prfm", []>;
OpenPOWER on IntegriCloud