1 ; RUN: opt -simplifycfg -instcombine < %s -simplifycfg-merge-cond-stores=true -simplifycfg-merge-cond-stores-aggressively=false -phi-node-folding-threshold=2 -S | FileCheck %s
3 ; CHECK-LABEL: @test_simple
4 ; This test should succeed and end up if-converted.
5 ; CHECK: icmp eq i32 %b, 0
6 ; CHECK-NEXT: icmp ne i32 %a, 0
7 ; CHECK-NEXT: xor i1 %x2, true
8 ; CHECK-NEXT: %[[x:.*]] = or i1 %{{.*}}, %{{.*}}
9 ; CHECK-NEXT: br i1 %[[x]]
13 define void @test_simple(i32* %p, i32 %a, i32 %b) {
15 %x1 = icmp eq i32 %a, 0
16 br i1 %x1, label %fallthrough, label %yes1
23 %x2 = icmp eq i32 %b, 0
24 br i1 %x2, label %end, label %yes2
34 ; CHECK-LABEL: @test_recursive
35 ; This test should entirely fold away, leaving one large basic block.
39 define void @test_recursive(i32* %p, i32 %a, i32 %b, i32 %c, i32 %d) {
41 %x1 = icmp eq i32 %a, 0
42 br i1 %x1, label %fallthrough, label %yes1
49 %x2 = icmp eq i32 %b, 0
50 br i1 %x2, label %next, label %yes2
57 %x3 = icmp eq i32 %c, 0
58 br i1 %x3, label %fallthrough2, label %yes3
62 br label %fallthrough2
65 %x4 = icmp eq i32 %d, 0
66 br i1 %x4, label %end, label %yes4
77 ; CHECK-LABEL: @test_not_ifconverted
78 ; The code in each diamond is too large - it won't be if-converted so our
79 ; heuristics should say no.
83 define void @test_not_ifconverted(i32* %p, i32 %a, i32 %b) {
85 %x1 = icmp eq i32 %a, 0
86 br i1 %x1, label %fallthrough, label %yes1
92 store i32 %y3, i32* %p
96 %x2 = icmp eq i32 %b, 0
97 br i1 %x2, label %end, label %yes2
101 %z2 = add i32 %z1, 24
102 %z3 = and i32 %z2, 67
103 store i32 %z3, i32* %p
110 ; CHECK-LABEL: @test_aliasing1
111 ; The store to %p clobbers the previous store, so if-converting this would
116 define void @test_aliasing1(i32* %p, i32 %a, i32 %b) {
118 %x1 = icmp eq i32 %a, 0
119 br i1 %x1, label %fallthrough, label %yes1
123 br label %fallthrough
126 %y1 = load i32, i32* %p
127 %x2 = icmp eq i32 %y1, 0
128 br i1 %x2, label %end, label %yes2
138 ; CHECK-LABEL: @test_aliasing2
139 ; The load from %q aliases with %p, so if-converting this would be illegal.
143 define void @test_aliasing2(i32* %p, i32* %q, i32 %a, i32 %b) {
145 %x1 = icmp eq i32 %a, 0
146 br i1 %x1, label %fallthrough, label %yes1
150 br label %fallthrough
153 %y1 = load i32, i32* %q
154 %x2 = icmp eq i32 %y1, 0
155 br i1 %x2, label %end, label %yes2
167 ; CHECK-LABEL: @test_diamond_simple
168 ; This should get if-converted.
172 define i32 @test_diamond_simple(i32* %p, i32* %q, i32 %a, i32 %b) {
174 %x1 = icmp eq i32 %a, 0
175 br i1 %x1, label %no1, label %yes1
179 br label %fallthrough
183 br label %fallthrough
186 %z2 = phi i32 [ %z1, %no1 ], [ 0, %yes1 ]
187 %x2 = icmp eq i32 %b, 0
188 br i1 %x2, label %no2, label %yes2
195 %z3 = sub i32 %z2, %b
199 %z4 = phi i32 [ %z3, %no2 ], [ 3, %yes2 ]
203 ; CHECK-LABEL: @test_diamond_alias3
204 ; Now there is a call to f() in the bottom branch. The store in the first
205 ; branch would now be reordered with respect to the call if we if-converted,
210 define i32 @test_diamond_alias3(i32* %p, i32* %q, i32 %a, i32 %b) {
212 %x1 = icmp eq i32 %a, 0
213 br i1 %x1, label %no1, label %yes1
217 br label %fallthrough
222 br label %fallthrough
225 %z2 = phi i32 [ %z1, %no1 ], [ 0, %yes1 ]
226 %x2 = icmp eq i32 %b, 0
227 br i1 %x2, label %no2, label %yes2
235 %z3 = sub i32 %z2, %b
239 %z4 = phi i32 [ %z3, %no2 ], [ 3, %yes2 ]