1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=gvn-hoist < %s | FileCheck %s
4 ; Check that the call and fcmp are hoisted.
5 define void @fun(float %__b, i1 %arg) minsize {
8 ; CHECK-NEXT: br label [[IF_THEN:%.*]]
10 ; CHECK-NEXT: [[TMP0:%.*]] = call float @llvm.fabs.f32(float [[__B:%.*]])
11 ; CHECK-NEXT: [[CMPINF7:%.*]] = fcmp oeq float [[TMP0]], 0x7FF0000000000000
12 ; CHECK-NEXT: br i1 %arg, label [[IF_THEN8:%.*]], label [[LOR_LHS_FALSE:%.*]]
13 ; CHECK: lor.lhs.false:
14 ; CHECK-NEXT: unreachable
16 ; CHECK-NEXT: ret void
21 if.then: ; preds = %entry
22 br i1 %arg, label %if.then8, label %lor.lhs.false
24 lor.lhs.false: ; preds = %if.then
25 %0 = call float @llvm.fabs.f32(float %__b) #2
26 %cmpinf7 = fcmp oeq float %0, 0x7FF0000000000000
29 if.then8: ; preds = %if.then
30 %1 = call float @llvm.fabs.f32(float %__b) #2
31 %cmpinf10 = fcmp oeq float %1, 0x7FF0000000000000
35 declare float @llvm.fabs.f32(float)
37 ; Check that extractvalues are not hoisted into entry, but that non-dependent
39 define i32 @foo(i32 %x) {
42 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], 1
43 ; CHECK-NEXT: [[TMP0:%.*]] = callbr { i32, i32 } asm sideeffect "somestuff", "=r,=r,!i"()
44 ; CHECK-NEXT: to label [[ASM_FALLTHROUGH:%.*]] [label %err.split]
45 ; CHECK: asm.fallthrough:
46 ; CHECK-NEXT: [[ASMRESULT:%.*]] = extractvalue { i32, i32 } [[TMP0]], 0
47 ; CHECK-NEXT: ret i32 [[ADD]]
49 ; CHECK-NEXT: [[ASMRESULT2:%.*]] = extractvalue { i32, i32 } [[TMP0]], 0
50 ; CHECK-NEXT: ret i32 [[ADD]]
53 %0 = callbr { i32, i32 } asm sideeffect "somestuff", "=r,=r,!i"()
54 to label %asm.fallthrough [label %err.split]
56 asm.fallthrough: ; preds = %entry
57 %asmresult = extractvalue { i32, i32 } %0, 0
58 %add = add nsw i32 %x, 1
61 err.split: ; preds = %entry
62 %asmresult2 = extractvalue { i32, i32 } %0, 0
63 %add2 = add nsw i32 %x, 1
67 ; Check that extractvalues and dependent adds are not hoisted into entry.
71 ; CHECK-NEXT: [[TMP0:%.*]] = callbr { i32, i32 } asm sideeffect "somestuff", "=r,=r,!i"()
72 ; CHECK-NEXT: to label [[ASM_FALLTHROUGH:%.*]] [label %err.split]
73 ; CHECK: asm.fallthrough:
74 ; CHECK-NEXT: [[ASMRESULT:%.*]] = extractvalue { i32, i32 } [[TMP0]], 0
75 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[ASMRESULT]], 1
76 ; CHECK-NEXT: ret i32 [[ADD]]
78 ; CHECK-NEXT: [[ASMRESULT2:%.*]] = extractvalue { i32, i32 } [[TMP0]], 0
79 ; CHECK-NEXT: [[ADD2:%.*]] = add nsw i32 [[ASMRESULT2]], 1
80 ; CHECK-NEXT: ret i32 [[ADD2]]
83 %0 = callbr { i32, i32 } asm sideeffect "somestuff", "=r,=r,!i"()
84 to label %asm.fallthrough [label %err.split]
86 asm.fallthrough: ; preds = %entry
87 %asmresult = extractvalue { i32, i32 } %0, 0
88 %add = add nsw i32 %asmresult, 1
91 err.split: ; preds = %entry
92 %asmresult2 = extractvalue { i32, i32 } %0, 0
93 %add2 = add nsw i32 %asmresult2, 1
97 ; Ensure we don't hoist loads that are modified by callbr.
100 ; CHECK-LABEL: @foo3(
102 ; CHECK-NEXT: callbr void asm "", "=*m,!i"(ptr elementtype(i32) @x)
103 ; CHECK-NEXT: to label [[ASM_FALLTHROUGH:%.*]] [label %err.split]
104 ; CHECK: asm.fallthrough:
105 ; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @x, align 4
106 ; CHECK-NEXT: ret i32 [[TMP0]]
108 ; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @x, align 4
109 ; CHECK-NEXT: ret i32 [[TMP1]]
112 callbr void asm "", "=*m,!i"(ptr elementtype(i32) @x)
113 to label %asm.fallthrough [label %err.split]
115 asm.fallthrough: ; preds = %entry
116 %0 = load i32, ptr @x
119 err.split: ; preds = %entry
120 %1 = load i32, ptr @x
124 ; Ensure we do hoist loads that aren't modified by callbr, if the callbr has
125 ; the attribute memory(argmem:readwrite).
128 ; CHECK-LABEL: @foo4(
130 ; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @y, align 4
131 ; CHECK-NEXT: callbr void asm "", "=*m,!i"(ptr elementtype(i32) @x) #[[ATTR2:[0-9]+]]
132 ; CHECK-NEXT: to label [[A:%.*]] [label %b]
134 ; CHECK-NEXT: ret i32 [[TMP0]]
136 ; CHECK-NEXT: ret i32 [[TMP0]]
139 callbr void asm "", "=*m,!i"(ptr elementtype(i32) @x) memory(argmem: readwrite)
140 to label %a [label %b]
143 %0 = load i32, ptr @y
147 %1 = load i32, ptr @y
151 ; Ensure we don't hoist loads that are modified by callbr, if the callbr has
152 ; the attribute memory(argmem:readwrite).
154 ; CHECK-LABEL: @foo5(
156 ; CHECK-NEXT: callbr void asm "", "=*m,!i"(ptr elementtype(i32) @x) #[[ATTR2]]
157 ; CHECK-NEXT: to label [[A:%.*]] [label %b]
159 ; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @x, align 4
160 ; CHECK-NEXT: ret i32 [[TMP0]]
162 ; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @x, align 4
163 ; CHECK-NEXT: ret i32 [[TMP1]]
166 callbr void asm "", "=*m,!i"(ptr elementtype(i32) @x) memory(argmem: readwrite)
167 to label %a [label %b]
170 %0 = load i32, ptr @x
174 %1 = load i32, ptr @x
178 ; Ensure we hoist loads that are modified by callbr, if the callbr has the
179 ; attribute memory(argmem:none).
181 ; CHECK-LABEL: @foo6(
183 ; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @x, align 4
184 ; CHECK-NEXT: callbr void asm "", "=*m,!i"(ptr elementtype(i32) @x) #[[ATTR3:[0-9]+]]
185 ; CHECK-NEXT: to label [[A:%.*]] [label %b]
187 ; CHECK-NEXT: ret i32 [[TMP0]]
189 ; CHECK-NEXT: ret i32 [[TMP0]]
192 callbr void asm "", "=*m,!i"(ptr elementtype(i32) @x) memory(argmem: none)
193 to label %a [label %b]
196 %0 = load i32, ptr @x
200 %1 = load i32, ptr @x