[ARM] Split large truncating MVE stores
[llvm-complete.git] / test / CodeGen / RISCV / hoist-global-addr-base.ll
blobdf8b31170695d510a611a22e806f79356e6bd7b5
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32  < %s | FileCheck  %s
4 %struct.S = type { [40 x i32], i32, i32, i32, [4100 x i32], i32, i32, i32 }
5 @s = common dso_local global %struct.S zeroinitializer, align 4
6 @foo = global [6 x i16] [i16 1, i16 2, i16 3, i16 4, i16 5, i16 0], align 2
7 @g = global [1048576 x i8] zeroinitializer, align 1
10 define dso_local void @multiple_stores() local_unnamed_addr nounwind {
11 ; CHECK-LABEL: multiple_stores:
12 ; CHECK:       # %bb.0: # %entry
13 ; CHECK-NEXT:    lui a0, %hi(s)
14 ; CHECK-NEXT:    addi a0, a0, %lo(s)
15 ; CHECK-NEXT:    addi a1, zero, 10
16 ; CHECK-NEXT:    sw a1, 160(a0)
17 ; CHECK-NEXT:    addi a1, zero, 20
18 ; CHECK-NEXT:    sw a1, 164(a0)
19 ; CHECK-NEXT:    ret
20 entry:
21   store i32 10, i32* getelementptr inbounds (%struct.S, %struct.S* @s, i32 0, i32 1), align 4
22   store i32 20, i32* getelementptr inbounds (%struct.S, %struct.S* @s, i32 0, i32 2), align 4
23   ret void
26 define dso_local void @control_flow_with_mem_access() local_unnamed_addr nounwind {
27 ; CHECK-LABEL: control_flow_with_mem_access:
28 ; CHECK:       # %bb.0: # %entry
29 ; CHECK-NEXT:    lui a0, %hi(s)
30 ; CHECK-NEXT:    addi a0, a0, %lo(s)
31 ; CHECK-NEXT:    lw a1, 164(a0)
32 ; CHECK-NEXT:    addi a2, zero, 1
33 ; CHECK-NEXT:    blt a1, a2, .LBB1_2
34 ; CHECK-NEXT:  # %bb.1: # %if.then
35 ; CHECK-NEXT:    addi a1, zero, 10
36 ; CHECK-NEXT:    sw a1, 160(a0)
37 ; CHECK-NEXT:  .LBB1_2: # %if.end
38 ; CHECK-NEXT:    ret
39 entry:
40   %0 = load i32, i32* getelementptr inbounds (%struct.S, %struct.S* @s, i32 0, i32 2), align 4
41   %cmp = icmp sgt i32 %0, 0
42   br i1 %cmp, label %if.then, label %if.end
44 if.then:                                          ; preds = %entry
45   store i32 10, i32* getelementptr inbounds (%struct.S, %struct.S* @s, i32 0, i32 1), align 4
46   br label %if.end
48 if.end:                                           ; preds = %if.then, %entry
49   ret void
52 ; This test checks that the offset is reconstructed correctly when
53 ; "addi" of the big offset has a negative immediate.
54 ; without peephole this generates:
55 ; lui  a1, %hi(g)
56 ; addi a1, a0, %lo(g)
57 ; lui  a0, 18     ---> offset
58 ; addi a0, a0, -160
59 ; add  a0, a0, a1  ---> base + offset.
60 define i8* @big_offset_neg_addi() nounwind {
61 ; CHECK-LABEL: big_offset_neg_addi:
62 ; CHECK:       # %bb.0:
63 ; CHECK-NEXT:    lui a0, %hi(g+73568)
64 ; CHECK-NEXT:    addi a0, a0, %lo(g+73568)
65 ; CHECK-NEXT:    ret
66   ret i8* getelementptr inbounds ([1048576 x i8], [1048576 x i8]* @g, i32 0, i32 73568)
69 ; This test checks for the case where the offset is only an LUI.
70 ; without peephole this generates:
71 ; lui  a0, %hi(g)
72 ; addi a0, a0, %lo(g)
73 ; lui  a1, 128     ---> offset
74 ; add  a0, a0, a1  ---> base + offset.
75 define i8* @big_offset_lui_tail() nounwind {
76 ; CHECK-LABEL: big_offset_lui_tail:
77 ; CHECK:       # %bb.0:
78 ; CHECK-NEXT:    lui a0, %hi(g+524288)
79 ; CHECK-NEXT:    addi a0, a0, %lo(g+524288)
80 ; CHECK-NEXT:    ret
81   ret i8* getelementptr inbounds ([1048576 x i8], [1048576 x i8]* @g, i32 0, i32 524288)
84 define dso_local i32* @big_offset_one_use() local_unnamed_addr nounwind {
85 ; CHECK-LABEL: big_offset_one_use:
86 ; CHECK:       # %bb.0: # %entry
87 ; CHECK-NEXT:    lui a0, %hi(s+16572)
88 ; CHECK-NEXT:    addi a0, a0, %lo(s+16572)
89 ; CHECK-NEXT:    ret
90 entry:
91   ret i32* getelementptr inbounds (%struct.S, %struct.S* @s, i32 0, i32 5)
94 define dso_local i32* @small_offset_one_use() local_unnamed_addr nounwind {
95 ; CHECK-LABEL: small_offset_one_use:
96 ; CHECK:       # %bb.0: # %entry
97 ; CHECK-NEXT:    lui a0, %hi(s+160)
98 ; CHECK-NEXT:    addi a0, a0, %lo(s+160)
99 ; CHECK-NEXT:    ret
100 entry:
101   ret i32* getelementptr inbounds (%struct.S, %struct.S* @s, i32 0, i32 1)
104 define dso_local i32* @control_flow_no_mem(i32 %n) local_unnamed_addr nounwind {
105 ; CHECK-LABEL: control_flow_no_mem:
106 ; CHECK:       # %bb.0: # %entry
107 ; CHECK-NEXT:    lui a0, %hi(s)
108 ; CHECK-NEXT:    addi a0, a0, %lo(s)
109 ; CHECK-NEXT:    lw a1, 164(a0)
110 ; CHECK-NEXT:    beqz a1, .LBB6_2
111 ; CHECK-NEXT:  # %bb.1: # %if.end
112 ; CHECK-NEXT:    addi a0, a0, 168
113 ; CHECK-NEXT:    ret
114 ; CHECK-NEXT:  .LBB6_2: # %if.then
115 ; CHECK-NEXT:    addi a0, a0, 160
116 ; CHECK-NEXT:    ret
117 entry:
118   %0 = load i32, i32* getelementptr inbounds (%struct.S, %struct.S* @s, i32 0, i32 2), align 4
119   %cmp = icmp eq i32 %0, 0
120   br i1 %cmp, label %if.then, label %if.end
121 if.then:                                          ; preds = %entry
122   ret i32* getelementptr inbounds (%struct.S, %struct.S* @s, i32 0, i32 1)
123 if.end:                                           ; preds = %if.then, %entry
124   ret i32* getelementptr inbounds (%struct.S, %struct.S* @s, i32 0, i32 3)
127 define dso_local i32 @load_half() nounwind {
128 ; CHECK-LABEL: load_half:
129 ; CHECK:       # %bb.0: # %entry
130 ; CHECK-NEXT:    addi sp, sp, -16
131 ; CHECK-NEXT:    sw ra, 12(sp)
132 ; CHECK-NEXT:    lui a0, %hi(foo+8)
133 ; CHECK-NEXT:    lhu a0, %lo(foo+8)(a0)
134 ; CHECK-NEXT:    addi a1, zero, 140
135 ; CHECK-NEXT:    bne a0, a1, .LBB7_2
136 ; CHECK-NEXT:  # %bb.1: # %if.end
137 ; CHECK-NEXT:    mv a0, zero
138 ; CHECK-NEXT:    lw ra, 12(sp)
139 ; CHECK-NEXT:    addi sp, sp, 16
140 ; CHECK-NEXT:    ret
141 ; CHECK-NEXT:  .LBB7_2: # %if.then
142 ; CHECK-NEXT:    call abort
143 entry:
144   %0 = load i16, i16* getelementptr inbounds ([6 x i16], [6 x i16]* @foo, i32 0, i32 4), align 2
145   %cmp = icmp eq i16 %0, 140
146   br i1 %cmp, label %if.end, label %if.then
148 if.then:
149   tail call void @abort()
150   unreachable
152 if.end:
153   ret i32 0
156 declare void @abort()
158 define dso_local void @one_store() local_unnamed_addr nounwind {
159 ; CHECK-LABEL: one_store:
160 ; CHECK:       # %bb.0: # %entry
161 ; CHECK-NEXT:    lui a0, %hi(s+160)
162 ; CHECK-NEXT:    addi a1, zero, 10
163 ; CHECK-NEXT:    sw a1, %lo(s+160)(a0)
164 ; CHECK-NEXT:    ret
165 entry:
166   store i32 10, i32* getelementptr inbounds (%struct.S, %struct.S* @s, i32 0, i32 1), align 4
167   ret void