[llvm] r341058 - [AArch64] Optimise load(adr address) to ldr address

David Green via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 30 04:55:16 PDT 2018


Author: dmgreen
Date: Thu Aug 30 04:55:16 2018
New Revision: 341058

URL: http://llvm.org/viewvc/llvm-project?rev=341058&view=rev
Log:
[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

Added:
    llvm/trunk/test/CodeGen/AArch64/ldradr.ll
Modified:
    llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td
    llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td
    llvm/trunk/test/CodeGen/AArch64/code-model-tiny-abs.ll
    llvm/trunk/test/CodeGen/AArch64/fpimm.ll
    llvm/trunk/test/CodeGen/AArch64/literal_pools_float.ll
    llvm/trunk/test/CodeGen/AArch64/tiny_model.ll

Modified: llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td?rev=341058&r1=341057&r2=341058&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td Thu Aug 30 04:55:16 2018
@@ -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;

Modified: llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td?rev=341058&r1=341057&r2=341058&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td Thu Aug 30 04:55:16 2018
@@ -1891,14 +1891,37 @@ def : InstAlias<"prfm $Rt, [$Rn]", (PRFM
 
 //---
 // (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", []>;

Modified: llvm/trunk/test/CodeGen/AArch64/code-model-tiny-abs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/code-model-tiny-abs.ll?rev=341058&r1=341057&r2=341058&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/code-model-tiny-abs.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/code-model-tiny-abs.ll Thu Aug 30 04:55:16 2018
@@ -33,16 +33,14 @@ define i32 @global_i32() {
 ; CHECK-LABEL: global_i32:
   %val = load i32, i32* @var32
   ret i32 %val
-; CHECK: adr x[[ADDR_REG:[0-9]+]], var32
-; CHECK: ldr w0, [x[[ADDR_REG]]]
+; CHECK: ldr w0, var32
 }
 
 define i64 @global_i64() {
 ; CHECK-LABEL: global_i64:
   %val = load i64, i64* @var64
   ret i64 %val
-; CHECK: adr x[[ADDR_REG:[0-9]+]], var64
-; CHECK: ldr x0, [x[[ADDR_REG]]]
+; CHECK: ldr x0, var64
 }
 
 define <2 x i64> @constpool() {

Modified: llvm/trunk/test/CodeGen/AArch64/fpimm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/fpimm.ll?rev=341058&r1=341057&r2=341058&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/fpimm.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/fpimm.ll Thu Aug 30 04:55:16 2018
@@ -19,7 +19,7 @@ define void @check_float() {
   %newval2 = fadd float %val, 128.0
   store volatile float %newval2, float* @varf32
 ; CHECK-DAG: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{#?}}:lo12:.LCPI0_0
-; TINY-DAG: ldr {{s[0-9]+}}, [{{x[0-9]+}}]
+; TINY-DAG: ldr {{s[0-9]+}}, .LCPI0_0
 
 ; CHECK: ret
 ; TINY: ret
@@ -39,7 +39,7 @@ define void @check_double() {
   %newval2 = fadd double %val, 128.0
   store volatile double %newval2, double* @varf64
 ; CHECK-DAG: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{#?}}:lo12:.LCPI1_0
-; TINY-DAG: ldr {{d[0-9]+}}, [{{x[0-9]+}}]
+; TINY-DAG: ldr {{d[0-9]+}}, .LCPI1_0
 
 ; CHECK: ret
 ; TINY: ret
@@ -51,8 +51,7 @@ define void @check_double() {
 ; LARGE-NEXT:  movk [[REG]], #16457, lsl #16
 ; LARGE-NEXT:  fmov s0, [[REG]]
 ; TINY-LABEL: check_float2
-; TINY:       adr     x[[REG:[0-9]+]], .LCPI2_0
-; TINY-NEXT:  ldr     s0, [x[[REG]]]
+; TINY:  ldr     s0, .LCPI2_0
 define float @check_float2() {
   ret float 3.14159274101257324218750
 }
@@ -64,8 +63,7 @@ define float @check_float2() {
 ; LARGE-NEXT:  movk [[REG]], #16393, lsl #48
 ; LARGE-NEXT:  fmov d0, [[REG]]
 ; TINY-LABEL: check_double2
-; TINY:       adr     x[[REG:[0-9]+]], .LCPI3_0
-; TINY-NEXT:  ldr     d0, [x[[REG]]]
+; TINY:  ldr     d0, .LCPI3_0
 define double @check_double2() {
   ret double 3.1415926535897931159979634685441851615905761718750
 }

Added: llvm/trunk/test/CodeGen/AArch64/ldradr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/ldradr.ll?rev=341058&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/ldradr.ll (added)
+++ llvm/trunk/test/CodeGen/AArch64/ldradr.ll Thu Aug 30 04:55:16 2018
@@ -0,0 +1,132 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=aarch64-none-eabi -code-model=tiny -verify-machineinstrs | FileCheck %s
+
+%struct.T = type <{ i32, i64, i8, i32 }>
+
+ at ptr = external local_unnamed_addr global i32*, align 8
+ at ch = external local_unnamed_addr global i32, align 4
+ at ch8 = external local_unnamed_addr global i8, align 4
+ at t = external local_unnamed_addr global %struct.T, align 4
+ at t2 = external local_unnamed_addr global %struct.T, align 2
+ at f = external local_unnamed_addr global float, align 4
+
+define i32 @barp() {
+; CHECK-LABEL: barp:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    ldr x8, ptr
+; CHECK-NEXT:    ldr w0, [x8]
+; CHECK-NEXT:    ret
+entry:
+  %0 = load i32*, i32** @ptr, align 8
+  %1 = load i32, i32* %0, align 4
+  ret i32 %1
+}
+
+define i32 @barch() {
+; CHECK-LABEL: barch:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    ldr w0, ch
+; CHECK-NEXT:    ret
+entry:
+  %0 = load i32, i32* @ch, align 4
+  ret i32 %0
+}
+
+define i32 @barta() {
+; CHECK-LABEL: barta:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    ldr w0, t
+; CHECK-NEXT:    ret
+entry:
+  %0 = load i32, i32* getelementptr inbounds (%struct.T, %struct.T* @t, i64 0, i32 0), align 4
+  ret i32 %0
+}
+
+define i64 @bartb() {
+; CHECK-LABEL: bartb:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    ldr x0, t+4
+; CHECK-NEXT:    ret
+entry:
+  %0 = load i64, i64* getelementptr inbounds (%struct.T, %struct.T* @t, i64 0, i32 1), align 8
+  ret i64 %0
+}
+
+define i32 @bartc() {
+; CHECK-LABEL: bartc:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    adr x8, t+13
+; CHECK-NEXT:    ldr w0, [x8]
+; CHECK-NEXT:    ret
+entry:
+  %0 = load i32, i32* getelementptr inbounds (%struct.T, %struct.T* @t, i64 0, i32 3), align 1
+  ret i32 %0
+}
+
+define i32 @bart2a() {
+; CHECK-LABEL: bart2a:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    adr x8, t2
+; CHECK-NEXT:    ldr w0, [x8]
+; CHECK-NEXT:    ret
+entry:
+  %0 = load i32, i32* getelementptr inbounds (%struct.T, %struct.T* @t2, i64 0, i32 0), align 2
+  ret i32 %0
+}
+
+define i64 @zextload() {
+; CHECK-LABEL: zextload:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    ldr w0, ch
+; CHECK-NEXT:    ret
+entry:
+  %0 = load i32, i32* @ch, align 4
+  %1 = zext i32 %0 to i64
+  ret i64 %1
+}
+
+define i64 @zextload8() {
+; CHECK-LABEL: zextload8:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    adr x8, ch8
+; CHECK-NEXT:    ldrb w0, [x8]
+; CHECK-NEXT:    ret
+entry:
+  %0 = load i8, i8* @ch8, align 4
+  %1 = zext i8 %0 to i64
+  ret i64 %1
+}
+
+define i64 @sextload() {
+; CHECK-LABEL: sextload:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    ldrsw x0, ch
+; CHECK-NEXT:    ret
+entry:
+  %0 = load i32, i32* @ch, align 4
+  %1 = sext i32 %0 to i64
+  ret i64 %1
+}
+
+define i64 @sextload8() {
+; CHECK-LABEL: sextload8:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    adr x8, ch8
+; CHECK-NEXT:    ldrsb x0, [x8]
+; CHECK-NEXT:    ret
+entry:
+  %0 = load i8, i8* @ch8, align 4
+  %1 = sext i8 %0 to i64
+  ret i64 %1
+}
+
+define float @floatload() {
+; CHECK-LABEL: floatload:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    ldr s0, f
+; CHECK-NEXT:    ret
+entry:
+  %0 = load float, float* @f, align 4
+  ret float %0
+}
+

Modified: llvm/trunk/test/CodeGen/AArch64/literal_pools_float.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/literal_pools_float.ll?rev=341058&r1=341057&r2=341058&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/literal_pools_float.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/literal_pools_float.ll Thu Aug 30 04:55:16 2018
@@ -17,8 +17,7 @@ define void @floating_lits() {
 ; CHECK: ldr [[LIT128:s[0-9]+]], [x[[LITBASE]], {{#?}}:lo12:[[CURLIT]]]
 ; CHECK-NOFP-NOT: ldr {{s[0-9]+}},
 
-; CHECK-TINY: adr x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI[0-9]+_[0-9]+]]
-; CHECK-TINY: ldr [[LIT128:s[0-9]+]], [x[[LITBASE]]]
+; CHECK-TINY: ldr [[LIT128:s[0-9]+]], [[CURLIT:.LCPI[0-9]+_[0-9]+]]
 ; CHECK-NOFP-TINY-NOT: ldr {{s[0-9]+}},
 
 ; CHECK-LARGE: movz x[[LITADDR:[0-9]+]], #:abs_g0_nc:[[CURLIT:.LCPI[0-9]+_[0-9]+]]
@@ -39,8 +38,7 @@ define void @floating_lits() {
 ; CHECK-NOFP-NOT: ldr {{d[0-9]+}},
 ; CHECK-NOFP-NOT: fadd
 
-; CHECK-TINY: adr x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI[0-9]+_[0-9]+]]
-; CHECK-TINY: ldr [[LIT129:d[0-9]+]], [x[[LITBASE]]]
+; CHECK-TINY: ldr [[LIT129:d[0-9]+]], [[CURLIT:.LCPI[0-9]+_[0-9]+]]
 ; CHECK-NOFP-TINY-NOT: ldr {{d[0-9]+}},
 ; CHECK-NOFP-TINY-NOT: fadd
 

Modified: llvm/trunk/test/CodeGen/AArch64/tiny_model.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/tiny_model.ll?rev=341058&r1=341057&r2=341058&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/tiny_model.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/tiny_model.ll Thu Aug 30 04:55:16 2018
@@ -89,9 +89,8 @@ define void @foo3() {
 ; CHECK-LABEL: foo3:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    adr x8, src
-; CHECK-NEXT:    adr x9, ptr
 ; CHECK-NEXT:    ldrb w8, [x8]
-; CHECK-NEXT:    ldr x9, [x9]
+; CHECK-NEXT:    ldr x9, ptr
 ; CHECK-NEXT:    strb w8, [x9]
 ; CHECK-NEXT:    ret
 ;
@@ -209,9 +208,8 @@ define void @bar3() {
 ; CHECK-LABEL: bar3:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    adr x8, lsrc
-; CHECK-NEXT:    adr x9, lptr
 ; CHECK-NEXT:    ldrb w8, [x8]
-; CHECK-NEXT:    ldr x9, [x9]
+; CHECK-NEXT:    ldr x9, lptr
 ; CHECK-NEXT:    strb w8, [x9]
 ; CHECK-NEXT:    ret
 ;
@@ -227,9 +225,8 @@ define void @bar3() {
 ; CHECK-PIC-LABEL: bar3:
 ; CHECK-PIC:       // %bb.0: // %entry
 ; CHECK-PIC-NEXT:    adr x8, lsrc
-; CHECK-PIC-NEXT:    adr x9, lptr
 ; CHECK-PIC-NEXT:    ldrb w8, [x8]
-; CHECK-PIC-NEXT:    ldr x9, [x9]
+; CHECK-PIC-NEXT:    ldr x9, lptr
 ; CHECK-PIC-NEXT:    strb w8, [x9]
 ; CHECK-PIC-NEXT:    ret
 ;
@@ -329,9 +326,8 @@ define void @baz3() {
 ; CHECK-LABEL: baz3:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    adr x8, lbsrc
-; CHECK-NEXT:    adr x9, lptr
 ; CHECK-NEXT:    ldrb w8, [x8]
-; CHECK-NEXT:    ldr x9, [x9]
+; CHECK-NEXT:    ldr x9, lptr
 ; CHECK-NEXT:    strb w8, [x9]
 ; CHECK-NEXT:    ret
 ;
@@ -347,9 +343,8 @@ define void @baz3() {
 ; CHECK-PIC-LABEL: baz3:
 ; CHECK-PIC:       // %bb.0: // %entry
 ; CHECK-PIC-NEXT:    adr x8, lbsrc
-; CHECK-PIC-NEXT:    adr x9, lptr
 ; CHECK-PIC-NEXT:    ldrb w8, [x8]
-; CHECK-PIC-NEXT:    ldr x9, [x9]
+; CHECK-PIC-NEXT:    ldr x9, lptr
 ; CHECK-PIC-NEXT:    strb w8, [x9]
 ; CHECK-PIC-NEXT:    ret
 ;




More information about the llvm-commits mailing list