Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 8f4233c

Browse files
committed
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@341058 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent e7278ca commit 8f4233c

File tree

7 files changed

+177
-33
lines changed

7 files changed

+177
-33
lines changed

lib/Target/AArch64/AArch64InstrFormats.td

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2853,10 +2853,10 @@ def am_ldrlit : Operand<iPTR> {
28532853
let OperandType = "OPERAND_PCREL";
28542854
}
28552855

2856-
let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2857-
class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm>
2856+
let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in
2857+
class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat>
28582858
: I<(outs regtype:$Rt), (ins am_ldrlit:$label),
2859-
asm, "\t$Rt, $label", "", []>,
2859+
asm, "\t$Rt, $label", "", pat>,
28602860
Sched<[WriteLD]> {
28612861
bits<5> Rt;
28622862
bits<19> label;

lib/Target/AArch64/AArch64InstrInfo.td

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1891,14 +1891,37 @@ def : InstAlias<"prfm $Rt, [$Rn]", (PRFMui prfop:$Rt, GPR64sp:$Rn, 0)>;
18911891

18921892
//---
18931893
// (literal)
1894-
def LDRWl : LoadLiteral<0b00, 0, GPR32z, "ldr">;
1895-
def LDRXl : LoadLiteral<0b01, 0, GPR64z, "ldr">;
1896-
def LDRSl : LoadLiteral<0b00, 1, FPR32Op, "ldr">;
1897-
def LDRDl : LoadLiteral<0b01, 1, FPR64Op, "ldr">;
1898-
def LDRQl : LoadLiteral<0b10, 1, FPR128Op, "ldr">;
1894+
1895+
def alignedglobal : PatLeaf<(iPTR iPTR:$label), [{
1896+
if (auto *G = dyn_cast<GlobalAddressSDNode>(N)) {
1897+
const DataLayout &DL = MF->getDataLayout();
1898+
unsigned Align = G->getGlobal()->getPointerAlignment(DL);
1899+
return Align >= 4 && G->getOffset() % 4 == 0;
1900+
}
1901+
if (auto *C = dyn_cast<ConstantPoolSDNode>(N))
1902+
return C->getAlignment() >= 4 && C->getOffset() % 4 == 0;
1903+
return false;
1904+
}]>;
1905+
1906+
def LDRWl : LoadLiteral<0b00, 0, GPR32z, "ldr",
1907+
[(set GPR32z:$Rt, (load (AArch64adr alignedglobal:$label)))]>;
1908+
def LDRXl : LoadLiteral<0b01, 0, GPR64z, "ldr",
1909+
[(set GPR64z:$Rt, (load (AArch64adr alignedglobal:$label)))]>;
1910+
def LDRSl : LoadLiteral<0b00, 1, FPR32Op, "ldr",
1911+
[(set (f32 FPR32Op:$Rt), (load (AArch64adr alignedglobal:$label)))]>;
1912+
def LDRDl : LoadLiteral<0b01, 1, FPR64Op, "ldr",
1913+
[(set (f64 FPR64Op:$Rt), (load (AArch64adr alignedglobal:$label)))]>;
1914+
def LDRQl : LoadLiteral<0b10, 1, FPR128Op, "ldr",
1915+
[(set (f128 FPR128Op:$Rt), (load (AArch64adr alignedglobal:$label)))]>;
18991916

19001917
// load sign-extended word
1901-
def LDRSWl : LoadLiteral<0b10, 0, GPR64z, "ldrsw">;
1918+
def LDRSWl : LoadLiteral<0b10, 0, GPR64z, "ldrsw",
1919+
[(set GPR64z:$Rt, (sextloadi32 (AArch64adr alignedglobal:$label)))]>;
1920+
1921+
let AddedComplexity = 20 in {
1922+
def : Pat<(i64 (zextloadi32 (AArch64adr alignedglobal:$label))),
1923+
(SUBREG_TO_REG (i64 0), (LDRWl $label), sub_32)>;
1924+
}
19021925

19031926
// prefetch
19041927
def PRFMl : PrefetchLiteral<0b11, 0, "prfm", []>;

test/CodeGen/AArch64/code-model-tiny-abs.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,14 @@ define i32 @global_i32() {
3333
; CHECK-LABEL: global_i32:
3434
%val = load i32, i32* @var32
3535
ret i32 %val
36-
; CHECK: adr x[[ADDR_REG:[0-9]+]], var32
37-
; CHECK: ldr w0, [x[[ADDR_REG]]]
36+
; CHECK: ldr w0, var32
3837
}
3938

4039
define i64 @global_i64() {
4140
; CHECK-LABEL: global_i64:
4241
%val = load i64, i64* @var64
4342
ret i64 %val
44-
; CHECK: adr x[[ADDR_REG:[0-9]+]], var64
45-
; CHECK: ldr x0, [x[[ADDR_REG]]]
43+
; CHECK: ldr x0, var64
4644
}
4745

4846
define <2 x i64> @constpool() {

test/CodeGen/AArch64/fpimm.ll

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ define void @check_float() {
1919
%newval2 = fadd float %val, 128.0
2020
store volatile float %newval2, float* @varf32
2121
; CHECK-DAG: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{#?}}:lo12:.LCPI0_0
22-
; TINY-DAG: ldr {{s[0-9]+}}, [{{x[0-9]+}}]
22+
; TINY-DAG: ldr {{s[0-9]+}}, .LCPI0_0
2323

2424
; CHECK: ret
2525
; TINY: ret
@@ -39,7 +39,7 @@ define void @check_double() {
3939
%newval2 = fadd double %val, 128.0
4040
store volatile double %newval2, double* @varf64
4141
; CHECK-DAG: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{#?}}:lo12:.LCPI1_0
42-
; TINY-DAG: ldr {{d[0-9]+}}, [{{x[0-9]+}}]
42+
; TINY-DAG: ldr {{d[0-9]+}}, .LCPI1_0
4343

4444
; CHECK: ret
4545
; TINY: ret
@@ -51,8 +51,7 @@ define void @check_double() {
5151
; LARGE-NEXT: movk [[REG]], #16457, lsl #16
5252
; LARGE-NEXT: fmov s0, [[REG]]
5353
; TINY-LABEL: check_float2
54-
; TINY: adr x[[REG:[0-9]+]], .LCPI2_0
55-
; TINY-NEXT: ldr s0, [x[[REG]]]
54+
; TINY: ldr s0, .LCPI2_0
5655
define float @check_float2() {
5756
ret float 3.14159274101257324218750
5857
}
@@ -64,8 +63,7 @@ define float @check_float2() {
6463
; LARGE-NEXT: movk [[REG]], #16393, lsl #48
6564
; LARGE-NEXT: fmov d0, [[REG]]
6665
; TINY-LABEL: check_double2
67-
; TINY: adr x[[REG:[0-9]+]], .LCPI3_0
68-
; TINY-NEXT: ldr d0, [x[[REG]]]
66+
; TINY: ldr d0, .LCPI3_0
6967
define double @check_double2() {
7068
ret double 3.1415926535897931159979634685441851615905761718750
7169
}

test/CodeGen/AArch64/ldradr.ll

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc < %s -mtriple=aarch64-none-eabi -code-model=tiny -verify-machineinstrs | FileCheck %s
3+
4+
%struct.T = type <{ i32, i64, i8, i32 }>
5+
6+
@ptr = external local_unnamed_addr global i32*, align 8
7+
@ch = external local_unnamed_addr global i32, align 4
8+
@ch8 = external local_unnamed_addr global i8, align 4
9+
@t = external local_unnamed_addr global %struct.T, align 4
10+
@t2 = external local_unnamed_addr global %struct.T, align 2
11+
@f = external local_unnamed_addr global float, align 4
12+
13+
define i32 @barp() {
14+
; CHECK-LABEL: barp:
15+
; CHECK: // %bb.0: // %entry
16+
; CHECK-NEXT: ldr x8, ptr
17+
; CHECK-NEXT: ldr w0, [x8]
18+
; CHECK-NEXT: ret
19+
entry:
20+
%0 = load i32*, i32** @ptr, align 8
21+
%1 = load i32, i32* %0, align 4
22+
ret i32 %1
23+
}
24+
25+
define i32 @barch() {
26+
; CHECK-LABEL: barch:
27+
; CHECK: // %bb.0: // %entry
28+
; CHECK-NEXT: ldr w0, ch
29+
; CHECK-NEXT: ret
30+
entry:
31+
%0 = load i32, i32* @ch, align 4
32+
ret i32 %0
33+
}
34+
35+
define i32 @barta() {
36+
; CHECK-LABEL: barta:
37+
; CHECK: // %bb.0: // %entry
38+
; CHECK-NEXT: ldr w0, t
39+
; CHECK-NEXT: ret
40+
entry:
41+
%0 = load i32, i32* getelementptr inbounds (%struct.T, %struct.T* @t, i64 0, i32 0), align 4
42+
ret i32 %0
43+
}
44+
45+
define i64 @bartb() {
46+
; CHECK-LABEL: bartb:
47+
; CHECK: // %bb.0: // %entry
48+
; CHECK-NEXT: ldr x0, t+4
49+
; CHECK-NEXT: ret
50+
entry:
51+
%0 = load i64, i64* getelementptr inbounds (%struct.T, %struct.T* @t, i64 0, i32 1), align 8
52+
ret i64 %0
53+
}
54+
55+
define i32 @bartc() {
56+
; CHECK-LABEL: bartc:
57+
; CHECK: // %bb.0: // %entry
58+
; CHECK-NEXT: adr x8, t+13
59+
; CHECK-NEXT: ldr w0, [x8]
60+
; CHECK-NEXT: ret
61+
entry:
62+
%0 = load i32, i32* getelementptr inbounds (%struct.T, %struct.T* @t, i64 0, i32 3), align 1
63+
ret i32 %0
64+
}
65+
66+
define i32 @bart2a() {
67+
; CHECK-LABEL: bart2a:
68+
; CHECK: // %bb.0: // %entry
69+
; CHECK-NEXT: adr x8, t2
70+
; CHECK-NEXT: ldr w0, [x8]
71+
; CHECK-NEXT: ret
72+
entry:
73+
%0 = load i32, i32* getelementptr inbounds (%struct.T, %struct.T* @t2, i64 0, i32 0), align 2
74+
ret i32 %0
75+
}
76+
77+
define i64 @zextload() {
78+
; CHECK-LABEL: zextload:
79+
; CHECK: // %bb.0: // %entry
80+
; CHECK-NEXT: ldr w0, ch
81+
; CHECK-NEXT: ret
82+
entry:
83+
%0 = load i32, i32* @ch, align 4
84+
%1 = zext i32 %0 to i64
85+
ret i64 %1
86+
}
87+
88+
define i64 @zextload8() {
89+
; CHECK-LABEL: zextload8:
90+
; CHECK: // %bb.0: // %entry
91+
; CHECK-NEXT: adr x8, ch8
92+
; CHECK-NEXT: ldrb w0, [x8]
93+
; CHECK-NEXT: ret
94+
entry:
95+
%0 = load i8, i8* @ch8, align 4
96+
%1 = zext i8 %0 to i64
97+
ret i64 %1
98+
}
99+
100+
define i64 @sextload() {
101+
; CHECK-LABEL: sextload:
102+
; CHECK: // %bb.0: // %entry
103+
; CHECK-NEXT: ldrsw x0, ch
104+
; CHECK-NEXT: ret
105+
entry:
106+
%0 = load i32, i32* @ch, align 4
107+
%1 = sext i32 %0 to i64
108+
ret i64 %1
109+
}
110+
111+
define i64 @sextload8() {
112+
; CHECK-LABEL: sextload8:
113+
; CHECK: // %bb.0: // %entry
114+
; CHECK-NEXT: adr x8, ch8
115+
; CHECK-NEXT: ldrsb x0, [x8]
116+
; CHECK-NEXT: ret
117+
entry:
118+
%0 = load i8, i8* @ch8, align 4
119+
%1 = sext i8 %0 to i64
120+
ret i64 %1
121+
}
122+
123+
define float @floatload() {
124+
; CHECK-LABEL: floatload:
125+
; CHECK: // %bb.0: // %entry
126+
; CHECK-NEXT: ldr s0, f
127+
; CHECK-NEXT: ret
128+
entry:
129+
%0 = load float, float* @f, align 4
130+
ret float %0
131+
}
132+

test/CodeGen/AArch64/literal_pools_float.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ define void @floating_lits() {
1717
; CHECK: ldr [[LIT128:s[0-9]+]], [x[[LITBASE]], {{#?}}:lo12:[[CURLIT]]]
1818
; CHECK-NOFP-NOT: ldr {{s[0-9]+}},
1919

20-
; CHECK-TINY: adr x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI[0-9]+_[0-9]+]]
21-
; CHECK-TINY: ldr [[LIT128:s[0-9]+]], [x[[LITBASE]]]
20+
; CHECK-TINY: ldr [[LIT128:s[0-9]+]], [[CURLIT:.LCPI[0-9]+_[0-9]+]]
2221
; CHECK-NOFP-TINY-NOT: ldr {{s[0-9]+}},
2322

2423
; CHECK-LARGE: movz x[[LITADDR:[0-9]+]], #:abs_g0_nc:[[CURLIT:.LCPI[0-9]+_[0-9]+]]
@@ -39,8 +38,7 @@ define void @floating_lits() {
3938
; CHECK-NOFP-NOT: ldr {{d[0-9]+}},
4039
; CHECK-NOFP-NOT: fadd
4140

42-
; CHECK-TINY: adr x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI[0-9]+_[0-9]+]]
43-
; CHECK-TINY: ldr [[LIT129:d[0-9]+]], [x[[LITBASE]]]
41+
; CHECK-TINY: ldr [[LIT129:d[0-9]+]], [[CURLIT:.LCPI[0-9]+_[0-9]+]]
4442
; CHECK-NOFP-TINY-NOT: ldr {{d[0-9]+}},
4543
; CHECK-NOFP-TINY-NOT: fadd
4644

test/CodeGen/AArch64/tiny_model.ll

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,8 @@ define void @foo3() {
8989
; CHECK-LABEL: foo3:
9090
; CHECK: // %bb.0: // %entry
9191
; CHECK-NEXT: adr x8, src
92-
; CHECK-NEXT: adr x9, ptr
9392
; CHECK-NEXT: ldrb w8, [x8]
94-
; CHECK-NEXT: ldr x9, [x9]
93+
; CHECK-NEXT: ldr x9, ptr
9594
; CHECK-NEXT: strb w8, [x9]
9695
; CHECK-NEXT: ret
9796
;
@@ -209,9 +208,8 @@ define void @bar3() {
209208
; CHECK-LABEL: bar3:
210209
; CHECK: // %bb.0: // %entry
211210
; CHECK-NEXT: adr x8, lsrc
212-
; CHECK-NEXT: adr x9, lptr
213211
; CHECK-NEXT: ldrb w8, [x8]
214-
; CHECK-NEXT: ldr x9, [x9]
212+
; CHECK-NEXT: ldr x9, lptr
215213
; CHECK-NEXT: strb w8, [x9]
216214
; CHECK-NEXT: ret
217215
;
@@ -227,9 +225,8 @@ define void @bar3() {
227225
; CHECK-PIC-LABEL: bar3:
228226
; CHECK-PIC: // %bb.0: // %entry
229227
; CHECK-PIC-NEXT: adr x8, lsrc
230-
; CHECK-PIC-NEXT: adr x9, lptr
231228
; CHECK-PIC-NEXT: ldrb w8, [x8]
232-
; CHECK-PIC-NEXT: ldr x9, [x9]
229+
; CHECK-PIC-NEXT: ldr x9, lptr
233230
; CHECK-PIC-NEXT: strb w8, [x9]
234231
; CHECK-PIC-NEXT: ret
235232
;
@@ -329,9 +326,8 @@ define void @baz3() {
329326
; CHECK-LABEL: baz3:
330327
; CHECK: // %bb.0: // %entry
331328
; CHECK-NEXT: adr x8, lbsrc
332-
; CHECK-NEXT: adr x9, lptr
333329
; CHECK-NEXT: ldrb w8, [x8]
334-
; CHECK-NEXT: ldr x9, [x9]
330+
; CHECK-NEXT: ldr x9, lptr
335331
; CHECK-NEXT: strb w8, [x9]
336332
; CHECK-NEXT: ret
337333
;
@@ -347,9 +343,8 @@ define void @baz3() {
347343
; CHECK-PIC-LABEL: baz3:
348344
; CHECK-PIC: // %bb.0: // %entry
349345
; CHECK-PIC-NEXT: adr x8, lbsrc
350-
; CHECK-PIC-NEXT: adr x9, lptr
351346
; CHECK-PIC-NEXT: ldrb w8, [x8]
352-
; CHECK-PIC-NEXT: ldr x9, [x9]
347+
; CHECK-PIC-NEXT: ldr x9, lptr
353348
; CHECK-PIC-NEXT: strb w8, [x9]
354349
; CHECK-PIC-NEXT: ret
355350
;

0 commit comments

Comments
 (0)