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 2 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]] 10 ; CHECK: store 11 ; CHECK-NOT: store 12 ; CHECK: ret 13 define void @test_simple(i32* %p, i32 %a, i32 %b) { 14 entry: 15 %x1 = icmp eq i32 %a, 0 16 br i1 %x1, label %fallthrough, label %yes1 17 18 yes1: 19 store i32 0, i32* %p 20 br label %fallthrough 21 22 fallthrough: 23 %x2 = icmp eq i32 %b, 0 24 br i1 %x2, label %end, label %yes2 25 26 yes2: 27 store i32 1, i32* %p 28 br label %end 29 30 end: 31 ret void 32 } 33 34 ; CHECK-LABEL: @test_recursive 35 ; This test should entirely fold away, leaving one large basic block. 36 ; CHECK: store 37 ; CHECK-NOT: store 38 ; CHECK: ret 39 define void @test_recursive(i32* %p, i32 %a, i32 %b, i32 %c, i32 %d) { 40 entry: 41 %x1 = icmp eq i32 %a, 0 42 br i1 %x1, label %fallthrough, label %yes1 43 44 yes1: 45 store i32 0, i32* %p 46 br label %fallthrough 47 48 fallthrough: 49 %x2 = icmp eq i32 %b, 0 50 br i1 %x2, label %next, label %yes2 51 52 yes2: 53 store i32 1, i32* %p 54 br label %next 55 56 next: 57 %x3 = icmp eq i32 %c, 0 58 br i1 %x3, label %fallthrough2, label %yes3 59 60 yes3: 61 store i32 2, i32* %p 62 br label %fallthrough2 63 64 fallthrough2: 65 %x4 = icmp eq i32 %d, 0 66 br i1 %x4, label %end, label %yes4 67 68 yes4: 69 store i32 3, i32* %p 70 br label %end 71 72 73 end: 74 ret void 75 } 76 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. 80 ; CHECK: store 81 ; CHECK: store 82 ; CHECK: ret 83 define void @test_not_ifconverted(i32* %p, i32 %a, i32 %b) { 84 entry: 85 %x1 = icmp eq i32 %a, 0 86 br i1 %x1, label %fallthrough, label %yes1 87 88 yes1: 89 %y1 = or i32 %b, 55 90 %y2 = add i32 %y1, 24 91 %y3 = and i32 %y2, 67 92 store i32 %y3, i32* %p 93 br label %fallthrough 94 95 fallthrough: 96 %x2 = icmp eq i32 %b, 0 97 br i1 %x2, label %end, label %yes2 98 99 yes2: 100 %z1 = or i32 %a, 55 101 %z2 = add i32 %z1, 24 102 %z3 = and i32 %z2, 67 103 store i32 %z3, i32* %p 104 br label %end 105 106 end: 107 ret void 108 } 109 110 ; CHECK-LABEL: @test_aliasing1 111 ; The store to %p clobbers the previous store, so if-converting this would 112 ; be illegal. 113 ; CHECK: store 114 ; CHECK: store 115 ; CHECK: ret 116 define void @test_aliasing1(i32* %p, i32 %a, i32 %b) { 117 entry: 118 %x1 = icmp eq i32 %a, 0 119 br i1 %x1, label %fallthrough, label %yes1 120 121 yes1: 122 store i32 0, i32* %p 123 br label %fallthrough 124 125 fallthrough: 126 %y1 = load i32, i32* %p 127 %x2 = icmp eq i32 %y1, 0 128 br i1 %x2, label %end, label %yes2 129 130 yes2: 131 store i32 1, i32* %p 132 br label %end 133 134 end: 135 ret void 136 } 137 138 ; CHECK-LABEL: @test_aliasing2 139 ; The load from %q aliases with %p, so if-converting this would be illegal. 140 ; CHECK: store 141 ; CHECK: store 142 ; CHECK: ret 143 define void @test_aliasing2(i32* %p, i32* %q, i32 %a, i32 %b) { 144 entry: 145 %x1 = icmp eq i32 %a, 0 146 br i1 %x1, label %fallthrough, label %yes1 147 148 yes1: 149 store i32 0, i32* %p 150 br label %fallthrough 151 152 fallthrough: 153 %y1 = load i32, i32* %q 154 %x2 = icmp eq i32 %y1, 0 155 br i1 %x2, label %end, label %yes2 156 157 yes2: 158 store i32 1, i32* %p 159 br label %end 160 161 end: 162 ret void 163 } 164 165 declare void @f() 166 167 ; CHECK-LABEL: @test_diamond_simple 168 ; This should get if-converted. 169 ; CHECK: store 170 ; CHECK-NOT: store 171 ; CHECK: ret 172 define i32 @test_diamond_simple(i32* %p, i32* %q, i32 %a, i32 %b) { 173 entry: 174 %x1 = icmp eq i32 %a, 0 175 br i1 %x1, label %no1, label %yes1 176 177 yes1: 178 store i32 0, i32* %p 179 br label %fallthrough 180 181 no1: 182 %z1 = add i32 %a, %b 183 br label %fallthrough 184 185 fallthrough: 186 %z2 = phi i32 [ %z1, %no1 ], [ 0, %yes1 ] 187 %x2 = icmp eq i32 %b, 0 188 br i1 %x2, label %no2, label %yes2 189 190 yes2: 191 store i32 1, i32* %p 192 br label %end 193 194 no2: 195 %z3 = sub i32 %z2, %b 196 br label %end 197 198 end: 199 %z4 = phi i32 [ %z3, %no2 ], [ 3, %yes2 ] 200 ret i32 %z4 201 } 202 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, 206 ; so we must not. 207 ; CHECK: store 208 ; CHECK: store 209 ; CHECK: ret 210 define i32 @test_diamond_alias3(i32* %p, i32* %q, i32 %a, i32 %b) { 211 entry: 212 %x1 = icmp eq i32 %a, 0 213 br i1 %x1, label %no1, label %yes1 214 215 yes1: 216 store i32 0, i32* %p 217 br label %fallthrough 218 219 no1: 220 call void @f() 221 %z1 = add i32 %a, %b 222 br label %fallthrough 223 224 fallthrough: 225 %z2 = phi i32 [ %z1, %no1 ], [ 0, %yes1 ] 226 %x2 = icmp eq i32 %b, 0 227 br i1 %x2, label %no2, label %yes2 228 229 yes2: 230 store i32 1, i32* %p 231 br label %end 232 233 no2: 234 call void @f() 235 %z3 = sub i32 %z2, %b 236 br label %end 237 238 end: 239 %z4 = phi i32 [ %z3, %no2 ], [ 3, %yes2 ] 240 ret i32 %z4 241 } 242