1; RUN: opt < %s -correlated-propagation -S | FileCheck %s 2 3; CHECK-LABEL: @test0( 4define void @test0(i32 %a) { 5entry: 6 %cmp = icmp slt i32 %a, 100 7 br i1 %cmp, label %bb, label %exit 8 9bb: 10; CHECK: %add = add nsw i32 %a, 1 11 %add = add i32 %a, 1 12 br label %exit 13 14exit: 15 ret void 16} 17 18; CHECK-LABEL: @test1( 19define void @test1(i32 %a) { 20entry: 21 %cmp = icmp ult i32 %a, 100 22 br i1 %cmp, label %bb, label %exit 23 24bb: 25; CHECK: %add = add nuw nsw i32 %a, 1 26 %add = add i32 %a, 1 27 br label %exit 28 29exit: 30 ret void 31} 32 33; CHECK-LABEL: @test2( 34define void @test2(i32 %a) { 35entry: 36 %cmp = icmp ult i32 %a, -1 37 br i1 %cmp, label %bb, label %exit 38 39bb: 40; CHECK: %add = add nuw i32 %a, 1 41 %add = add i32 %a, 1 42 br label %exit 43 44exit: 45 ret void 46} 47 48; CHECK-LABEL: @test3( 49define void @test3(i32 %a) { 50entry: 51 %cmp = icmp ule i32 %a, -1 52 br i1 %cmp, label %bb, label %exit 53 54bb: 55; CHECK: %add = add i32 %a, 1 56 %add = add i32 %a, 1 57 br label %exit 58 59exit: 60 ret void 61} 62 63; CHECK-LABEL: @test4( 64define void @test4(i32 %a) { 65entry: 66 %cmp = icmp slt i32 %a, 2147483647 67 br i1 %cmp, label %bb, label %exit 68 69bb: 70; CHECK: %add = add nsw i32 %a, 1 71 %add = add i32 %a, 1 72 br label %exit 73 74exit: 75 ret void 76} 77 78; CHECK-LABEL: @test5( 79define void @test5(i32 %a) { 80entry: 81 %cmp = icmp sle i32 %a, 2147483647 82 br i1 %cmp, label %bb, label %exit 83 84bb: 85; CHECK: %add = add i32 %a, 1 86 %add = add i32 %a, 1 87 br label %exit 88 89exit: 90 ret void 91} 92 93; Check for a corner case where an integer value is represented with a constant 94; LVILatticeValue instead of constantrange. Check that we don't fail with an 95; assertion in this case. 96@b = global i32 0, align 4 97define void @test6(i32 %a) { 98bb: 99 %add = add i32 %a, ptrtoint (i32* @b to i32) 100 ret void 101} 102 103; Check that we can gather information for conditions is the form of 104; and ( i s< 100, Unknown ) 105; CHECK-LABEL: @test7( 106define void @test7(i32 %a, i1 %flag) { 107entry: 108 %cmp.1 = icmp slt i32 %a, 100 109 %cmp = and i1 %cmp.1, %flag 110 br i1 %cmp, label %bb, label %exit 111 112bb: 113; CHECK: %add = add nsw i32 %a, 1 114 %add = add i32 %a, 1 115 br label %exit 116 117exit: 118 ret void 119} 120 121; Check that we can gather information for conditions is the form of 122; and ( i s< 100, i s> 0 ) 123; CHECK-LABEL: @test8( 124define void @test8(i32 %a) { 125entry: 126 %cmp.1 = icmp slt i32 %a, 100 127 %cmp.2 = icmp sgt i32 %a, 0 128 %cmp = and i1 %cmp.1, %cmp.2 129 br i1 %cmp, label %bb, label %exit 130 131bb: 132; CHECK: %add = add nuw nsw i32 %a, 1 133 %add = add i32 %a, 1 134 br label %exit 135 136exit: 137 ret void 138} 139 140; Check that for conditions is the form of cond1 && cond2 we don't mistakenly 141; assume that !cond1 && !cond2 holds down to false path. 142; CHECK-LABEL: @test8_neg( 143define void @test8_neg(i32 %a) { 144entry: 145 %cmp.1 = icmp sge i32 %a, 100 146 %cmp.2 = icmp sle i32 %a, 0 147 %cmp = and i1 %cmp.1, %cmp.2 148 br i1 %cmp, label %exit, label %bb 149 150bb: 151; CHECK: %add = add i32 %a, 1 152 %add = add i32 %a, 1 153 br label %exit 154 155exit: 156 ret void 157} 158 159; Check that we can gather information for conditions is the form of 160; and ( i s< 100, and (i s> 0, Unknown ) 161; CHECK-LABEL: @test9( 162define void @test9(i32 %a, i1 %flag) { 163entry: 164 %cmp.1 = icmp slt i32 %a, 100 165 %cmp.2 = icmp sgt i32 %a, 0 166 %cmp.3 = and i1 %cmp.2, %flag 167 %cmp = and i1 %cmp.1, %cmp.3 168 br i1 %cmp, label %bb, label %exit 169 170bb: 171; CHECK: %add = add nuw nsw i32 %a, 1 172 %add = add i32 %a, 1 173 br label %exit 174 175exit: 176 ret void 177} 178 179; Check that we can gather information for conditions is the form of 180; and ( i s< Unknown, ... ) 181; CHECK-LABEL: @test10( 182define void @test10(i32 %a, i32 %b, i1 %flag) { 183entry: 184 %cmp.1 = icmp slt i32 %a, %b 185 %cmp = and i1 %cmp.1, %flag 186 br i1 %cmp, label %bb, label %exit 187 188bb: 189; CHECK: %add = add nsw i32 %a, 1 190 %add = add i32 %a, 1 191 br label %exit 192 193exit: 194 ret void 195} 196 197@limit = external global i32 198; CHECK-LABEL: @test11( 199define i32 @test11(i32* %p, i32 %i) { 200 %limit = load i32, i32* %p, !range !{i32 0, i32 2147483647} 201 %within.1 = icmp ugt i32 %limit, %i 202 %i.plus.7 = add i32 %i, 7 203 %within.2 = icmp ugt i32 %limit, %i.plus.7 204 %within = and i1 %within.1, %within.2 205 br i1 %within, label %then, label %else 206 207then: 208; CHECK: %i.plus.6 = add nuw nsw i32 %i, 6 209 %i.plus.6 = add i32 %i, 6 210 ret i32 %i.plus.6 211 212else: 213 ret i32 0 214} 215 216; Check that we can gather information for conditions is the form of 217; or ( i s>= 100, Unknown ) 218; CHECK-LABEL: @test12( 219define void @test12(i32 %a, i1 %flag) { 220entry: 221 %cmp.1 = icmp sge i32 %a, 100 222 %cmp = or i1 %cmp.1, %flag 223 br i1 %cmp, label %exit, label %bb 224 225bb: 226; CHECK: %add = add nsw i32 %a, 1 227 %add = add i32 %a, 1 228 br label %exit 229 230exit: 231 ret void 232} 233 234; Check that we can gather information for conditions is the form of 235; or ( i s>= 100, i s<= 0 ) 236; CHECK-LABEL: @test13( 237define void @test13(i32 %a) { 238entry: 239 %cmp.1 = icmp sge i32 %a, 100 240 %cmp.2 = icmp sle i32 %a, 0 241 %cmp = or i1 %cmp.1, %cmp.2 242 br i1 %cmp, label %exit, label %bb 243 244bb: 245; CHECK: %add = add nuw nsw i32 %a, 1 246 %add = add i32 %a, 1 247 br label %exit 248 249exit: 250 ret void 251} 252 253; Check that for conditions is the form of cond1 || cond2 we don't mistakenly 254; assume that cond1 || cond2 holds down to true path. 255; CHECK-LABEL: @test13_neg( 256define void @test13_neg(i32 %a) { 257entry: 258 %cmp.1 = icmp slt i32 %a, 100 259 %cmp.2 = icmp sgt i32 %a, 0 260 %cmp = or i1 %cmp.1, %cmp.2 261 br i1 %cmp, label %bb, label %exit 262 263bb: 264; CHECK: %add = add i32 %a, 1 265 %add = add i32 %a, 1 266 br label %exit 267 268exit: 269 ret void 270} 271 272; Check that we can gather information for conditions is the form of 273; or ( i s>=100, or (i s<= 0, Unknown ) 274; CHECK-LABEL: @test14( 275define void @test14(i32 %a, i1 %flag) { 276entry: 277 %cmp.1 = icmp sge i32 %a, 100 278 %cmp.2 = icmp sle i32 %a, 0 279 %cmp.3 = or i1 %cmp.2, %flag 280 %cmp = or i1 %cmp.1, %cmp.3 281 br i1 %cmp, label %exit, label %bb 282 283bb: 284; CHECK: %add = add nuw nsw i32 %a, 1 285 %add = add i32 %a, 1 286 br label %exit 287 288exit: 289 ret void 290} 291 292; Check that we can gather information for conditions is the form of 293; or ( i s>= Unknown, ... ) 294; CHECK-LABEL: @test15( 295define void @test15(i32 %a, i32 %b, i1 %flag) { 296entry: 297 %cmp.1 = icmp sge i32 %a, %b 298 %cmp = or i1 %cmp.1, %flag 299 br i1 %cmp, label %exit, label %bb 300 301bb: 302; CHECK: %add = add nsw i32 %a, 1 303 %add = add i32 %a, 1 304 br label %exit 305 306exit: 307 ret void 308} 309 310; single basic block loop 311; because the loop exit condition is SLT, we can supplement the iv add 312; (iv.next def) with an nsw. 313; CHECK-LABEL: @test16( 314define i32 @test16(i32* %n, i32* %a) { 315preheader: 316 br label %loop 317 318loop: 319; CHECK: %iv.next = add nsw i32 %iv, 1 320 %iv = phi i32 [ 0, %preheader ], [ %iv.next, %loop ] 321 %acc = phi i32 [ 0, %preheader ], [ %acc.curr, %loop ] 322 %x = load atomic i32, i32* %a unordered, align 8 323 fence acquire 324 %acc.curr = add i32 %acc, %x 325 %iv.next = add i32 %iv, 1 326 %nval = load atomic i32, i32* %n unordered, align 8 327 %cmp = icmp slt i32 %iv.next, %nval 328 br i1 %cmp, label %loop, label %exit 329 330exit: 331 ret i32 %acc.curr 332} 333