1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -S -analyze -scalar-evolution | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; Positive and negative tests for inferring flags like nsw from 4*9880d681SAndroid Build Coastguard Worker; reasoning about how a poison value from overflow would trigger 5*9880d681SAndroid Build Coastguard Worker; undefined behavior. 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Workerdefine void @foo() { 8*9880d681SAndroid Build Coastguard Worker ret void 9*9880d681SAndroid Build Coastguard Worker} 10*9880d681SAndroid Build Coastguard Worker 11*9880d681SAndroid Build Coastguard Worker; Example where an add should get the nsw flag, so that a sext can be 12*9880d681SAndroid Build Coastguard Worker; distributed over the add. 13*9880d681SAndroid Build Coastguard Workerdefine void @test-add-nsw(float* %input, i32 %offset, i32 %numIterations) { 14*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-nsw 15*9880d681SAndroid Build Coastguard Workerentry: 16*9880d681SAndroid Build Coastguard Worker br label %loop 17*9880d681SAndroid Build Coastguard Workerloop: 18*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 21*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nsw> 22*9880d681SAndroid Build Coastguard Worker %index32 = add nsw i32 %i, %offset 23*9880d681SAndroid Build Coastguard Worker 24*9880d681SAndroid Build Coastguard Worker; CHECK: %index64 = 25*9880d681SAndroid Build Coastguard Worker; CHECK: --> {(sext i32 %offset to i64),+,1}<nsw> 26*9880d681SAndroid Build Coastguard Worker %index64 = sext i32 %index32 to i64 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i64 %index64 29*9880d681SAndroid Build Coastguard Worker %nexti = add nsw i32 %i, 1 30*9880d681SAndroid Build Coastguard Worker %f = load float, float* %ptr, align 4 31*9880d681SAndroid Build Coastguard Worker call void @foo() 32*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 33*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 34*9880d681SAndroid Build Coastguard Workerexit: 35*9880d681SAndroid Build Coastguard Worker ret void 36*9880d681SAndroid Build Coastguard Worker} 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Worker; Example where an add should get the nuw flag. 39*9880d681SAndroid Build Coastguard Workerdefine void @test-add-nuw(float* %input, i32 %offset, i32 %numIterations) { 40*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-nuw 41*9880d681SAndroid Build Coastguard Workerentry: 42*9880d681SAndroid Build Coastguard Worker br label %loop 43*9880d681SAndroid Build Coastguard Workerloop: 44*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 47*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nuw> 48*9880d681SAndroid Build Coastguard Worker %index32 = add nuw i32 %i, %offset 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i32 %index32 51*9880d681SAndroid Build Coastguard Worker %nexti = add nuw i32 %i, 1 52*9880d681SAndroid Build Coastguard Worker %f = load float, float* %ptr, align 4 53*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 54*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Workerexit: 57*9880d681SAndroid Build Coastguard Worker ret void 58*9880d681SAndroid Build Coastguard Worker} 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Workerdefine void @test-add-nuw-from-icmp(float* %input, i32 %offset, 61*9880d681SAndroid Build Coastguard Worker i32 %numIterations) { 62*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-nuw-from-icmp 63*9880d681SAndroid Build Coastguard Workerentry: 64*9880d681SAndroid Build Coastguard Worker br label %loop 65*9880d681SAndroid Build Coastguard Workerloop: 66*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 67*9880d681SAndroid Build Coastguard Worker 68*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 69*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nuw> 70*9880d681SAndroid Build Coastguard Worker %index32 = add nuw i32 %i, %offset 71*9880d681SAndroid Build Coastguard Worker %cmp = icmp sgt i32 %index32, 0 72*9880d681SAndroid Build Coastguard Worker %cmp.idx = sext i1 %cmp to i32 73*9880d681SAndroid Build Coastguard Worker 74*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i32 %cmp.idx 75*9880d681SAndroid Build Coastguard Worker %nexti = add nuw i32 %i, 1 76*9880d681SAndroid Build Coastguard Worker %f = load float, float* %ptr, align 4 77*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 78*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 79*9880d681SAndroid Build Coastguard Worker 80*9880d681SAndroid Build Coastguard Workerexit: 81*9880d681SAndroid Build Coastguard Worker ret void 82*9880d681SAndroid Build Coastguard Worker} 83*9880d681SAndroid Build Coastguard Worker 84*9880d681SAndroid Build Coastguard Worker; With no load to trigger UB from poison, we cannot infer nsw. 85*9880d681SAndroid Build Coastguard Workerdefine void @test-add-no-load(float* %input, i32 %offset, i32 %numIterations) { 86*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-no-load 87*9880d681SAndroid Build Coastguard Workerentry: 88*9880d681SAndroid Build Coastguard Worker br label %loop 89*9880d681SAndroid Build Coastguard Workerloop: 90*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 93*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nw> 94*9880d681SAndroid Build Coastguard Worker %index32 = add nsw i32 %i, %offset 95*9880d681SAndroid Build Coastguard Worker 96*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i32 %index32 97*9880d681SAndroid Build Coastguard Worker %nexti = add nuw i32 %i, 1 98*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 99*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 100*9880d681SAndroid Build Coastguard Worker 101*9880d681SAndroid Build Coastguard Workerexit: 102*9880d681SAndroid Build Coastguard Worker ret void 103*9880d681SAndroid Build Coastguard Worker} 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Worker; The current code is only supposed to look at the loop header, so 106*9880d681SAndroid Build Coastguard Worker; it should not infer nsw in this case, as that would require looking 107*9880d681SAndroid Build Coastguard Worker; outside the loop header. 108*9880d681SAndroid Build Coastguard Workerdefine void @test-add-not-header(float* %input, i32 %offset, i32 %numIterations) { 109*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-not-header 110*9880d681SAndroid Build Coastguard Workerentry: 111*9880d681SAndroid Build Coastguard Worker br label %loop 112*9880d681SAndroid Build Coastguard Workerloop: 113*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] 114*9880d681SAndroid Build Coastguard Worker br label %loop2 115*9880d681SAndroid Build Coastguard Workerloop2: 116*9880d681SAndroid Build Coastguard Worker 117*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 118*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nw> 119*9880d681SAndroid Build Coastguard Worker %index32 = add nsw i32 %i, %offset 120*9880d681SAndroid Build Coastguard Worker 121*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i32 %index32 122*9880d681SAndroid Build Coastguard Worker %nexti = add nsw i32 %i, 1 123*9880d681SAndroid Build Coastguard Worker %f = load float, float* %ptr, align 4 124*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 125*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 126*9880d681SAndroid Build Coastguard Workerexit: 127*9880d681SAndroid Build Coastguard Worker ret void 128*9880d681SAndroid Build Coastguard Worker} 129*9880d681SAndroid Build Coastguard Worker 130*9880d681SAndroid Build Coastguard Worker; Same thing as test-add-not-header, but in this case only the load 131*9880d681SAndroid Build Coastguard Worker; instruction is outside the loop header. 132*9880d681SAndroid Build Coastguard Workerdefine void @test-add-not-header2(float* %input, i32 %offset, i32 %numIterations) { 133*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-not-header2 134*9880d681SAndroid Build Coastguard Workerentry: 135*9880d681SAndroid Build Coastguard Worker br label %loop 136*9880d681SAndroid Build Coastguard Workerloop: 137*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] 138*9880d681SAndroid Build Coastguard Worker 139*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 140*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nsw> 141*9880d681SAndroid Build Coastguard Worker %index32 = add nsw i32 %i, %offset 142*9880d681SAndroid Build Coastguard Worker 143*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i32 %index32 144*9880d681SAndroid Build Coastguard Worker %nexti = add nsw i32 %i, 1 145*9880d681SAndroid Build Coastguard Worker br label %loop2 146*9880d681SAndroid Build Coastguard Workerloop2: 147*9880d681SAndroid Build Coastguard Worker %f = load float, float* %ptr, align 4 148*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 149*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 150*9880d681SAndroid Build Coastguard Workerexit: 151*9880d681SAndroid Build Coastguard Worker ret void 152*9880d681SAndroid Build Coastguard Worker} 153*9880d681SAndroid Build Coastguard Worker 154*9880d681SAndroid Build Coastguard Worker; Similar to test-add-not-header, but in this case the load 155*9880d681SAndroid Build Coastguard Worker; instruction may not be executed. 156*9880d681SAndroid Build Coastguard Workerdefine void @test-add-not-header3(float* %input, i32 %offset, i32 %numIterations, 157*9880d681SAndroid Build Coastguard Worker i1* %cond_buf) { 158*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-not-header3 159*9880d681SAndroid Build Coastguard Workerentry: 160*9880d681SAndroid Build Coastguard Worker br label %loop 161*9880d681SAndroid Build Coastguard Workerloop: 162*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] 163*9880d681SAndroid Build Coastguard Worker 164*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 165*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nw> 166*9880d681SAndroid Build Coastguard Worker %index32 = add nsw i32 %i, %offset 167*9880d681SAndroid Build Coastguard Worker 168*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i32 %index32 169*9880d681SAndroid Build Coastguard Worker %nexti = add nsw i32 %i, 1 170*9880d681SAndroid Build Coastguard Worker %cond = load volatile i1, i1* %cond_buf 171*9880d681SAndroid Build Coastguard Worker br i1 %cond, label %loop2, label %exit 172*9880d681SAndroid Build Coastguard Workerloop2: 173*9880d681SAndroid Build Coastguard Worker %f = load float, float* %ptr, align 4 174*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 175*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 176*9880d681SAndroid Build Coastguard Workerexit: 177*9880d681SAndroid Build Coastguard Worker ret void 178*9880d681SAndroid Build Coastguard Worker} 179*9880d681SAndroid Build Coastguard Worker 180*9880d681SAndroid Build Coastguard Worker; Same thing as test-add-not-header2, except we have a few extra 181*9880d681SAndroid Build Coastguard Worker; blocks. 182*9880d681SAndroid Build Coastguard Workerdefine void @test-add-not-header4(float* %input, i32 %offset, i32 %numIterations) { 183*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-not-header4 184*9880d681SAndroid Build Coastguard Workerentry: 185*9880d681SAndroid Build Coastguard Worker br label %loop 186*9880d681SAndroid Build Coastguard Workerloop: 187*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] 188*9880d681SAndroid Build Coastguard Worker 189*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 190*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nsw> 191*9880d681SAndroid Build Coastguard Worker %index32 = add nsw i32 %i, %offset 192*9880d681SAndroid Build Coastguard Worker 193*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i32 %index32 194*9880d681SAndroid Build Coastguard Worker %nexti = add nsw i32 %i, 1 195*9880d681SAndroid Build Coastguard Worker br label %loop3 196*9880d681SAndroid Build Coastguard Workerloop3: 197*9880d681SAndroid Build Coastguard Worker br label %loop4 198*9880d681SAndroid Build Coastguard Workerloop4: 199*9880d681SAndroid Build Coastguard Worker br label %loop2 200*9880d681SAndroid Build Coastguard Workerloop2: 201*9880d681SAndroid Build Coastguard Worker %f = load float, float* %ptr, align 4 202*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 203*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 204*9880d681SAndroid Build Coastguard Workerexit: 205*9880d681SAndroid Build Coastguard Worker ret void 206*9880d681SAndroid Build Coastguard Worker} 207*9880d681SAndroid Build Coastguard Worker 208*9880d681SAndroid Build Coastguard Worker; Demonstrate why we need a Visited set in llvm::isKnownNotFullPoison. 209*9880d681SAndroid Build Coastguard Workerdefine void @test-add-not-header5(float* %input, i32 %offset) { 210*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-not-header5 211*9880d681SAndroid Build Coastguard Workerentry: 212*9880d681SAndroid Build Coastguard Worker br label %loop 213*9880d681SAndroid Build Coastguard Workerloop: 214*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 215*9880d681SAndroid Build Coastguard Worker 216*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 217*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nw> 218*9880d681SAndroid Build Coastguard Worker %index32 = add nsw i32 %i, %offset 219*9880d681SAndroid Build Coastguard Worker 220*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i32 %index32 221*9880d681SAndroid Build Coastguard Worker %nexti = add nsw i32 %i, 1 222*9880d681SAndroid Build Coastguard Worker br label %loop 223*9880d681SAndroid Build Coastguard Worker 224*9880d681SAndroid Build Coastguard Workerexit: 225*9880d681SAndroid Build Coastguard Worker ret void 226*9880d681SAndroid Build Coastguard Worker} 227*9880d681SAndroid Build Coastguard Worker 228*9880d681SAndroid Build Coastguard Worker; The call instruction makes it not guaranteed that the add will be 229*9880d681SAndroid Build Coastguard Worker; executed, since it could run forever or throw an exception, so we 230*9880d681SAndroid Build Coastguard Worker; cannot assume that the UB is realized. 231*9880d681SAndroid Build Coastguard Workerdefine void @test-add-call(float* %input, i32 %offset, i32 %numIterations) { 232*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-call 233*9880d681SAndroid Build Coastguard Workerentry: 234*9880d681SAndroid Build Coastguard Worker br label %loop 235*9880d681SAndroid Build Coastguard Workerloop: 236*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 237*9880d681SAndroid Build Coastguard Worker 238*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 239*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nw> 240*9880d681SAndroid Build Coastguard Worker call void @foo() 241*9880d681SAndroid Build Coastguard Worker %index32 = add nsw i32 %i, %offset 242*9880d681SAndroid Build Coastguard Worker 243*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i32 %index32 244*9880d681SAndroid Build Coastguard Worker %nexti = add nsw i32 %i, 1 245*9880d681SAndroid Build Coastguard Worker %f = load float, float* %ptr, align 4 246*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 247*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 248*9880d681SAndroid Build Coastguard Workerexit: 249*9880d681SAndroid Build Coastguard Worker ret void 250*9880d681SAndroid Build Coastguard Worker} 251*9880d681SAndroid Build Coastguard Worker 252*9880d681SAndroid Build Coastguard Worker; Same issue as test-add-call, but this time the call is between the 253*9880d681SAndroid Build Coastguard Worker; producer of poison and the load that consumes it. 254*9880d681SAndroid Build Coastguard Workerdefine void @test-add-call2(float* %input, i32 %offset, i32 %numIterations) { 255*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-call2 256*9880d681SAndroid Build Coastguard Workerentry: 257*9880d681SAndroid Build Coastguard Worker br label %loop 258*9880d681SAndroid Build Coastguard Workerloop: 259*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 260*9880d681SAndroid Build Coastguard Worker 261*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 262*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nw> 263*9880d681SAndroid Build Coastguard Worker %index32 = add nsw i32 %i, %offset 264*9880d681SAndroid Build Coastguard Worker 265*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i32 %index32 266*9880d681SAndroid Build Coastguard Worker %nexti = add nsw i32 %i, 1 267*9880d681SAndroid Build Coastguard Worker call void @foo() 268*9880d681SAndroid Build Coastguard Worker %f = load float, float* %ptr, align 4 269*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 270*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 271*9880d681SAndroid Build Coastguard Workerexit: 272*9880d681SAndroid Build Coastguard Worker ret void 273*9880d681SAndroid Build Coastguard Worker} 274*9880d681SAndroid Build Coastguard Worker 275*9880d681SAndroid Build Coastguard Worker; Without inbounds, GEP does not propagate poison in the very 276*9880d681SAndroid Build Coastguard Worker; conservative approach used here. 277*9880d681SAndroid Build Coastguard Workerdefine void @test-add-no-inbounds(float* %input, i32 %offset, i32 %numIterations) { 278*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-no-inbounds 279*9880d681SAndroid Build Coastguard Workerentry: 280*9880d681SAndroid Build Coastguard Worker br label %loop 281*9880d681SAndroid Build Coastguard Workerloop: 282*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 283*9880d681SAndroid Build Coastguard Worker 284*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 285*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nw> 286*9880d681SAndroid Build Coastguard Worker %index32 = add nsw i32 %i, %offset 287*9880d681SAndroid Build Coastguard Worker 288*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr float, float* %input, i32 %index32 289*9880d681SAndroid Build Coastguard Worker %nexti = add nsw i32 %i, 1 290*9880d681SAndroid Build Coastguard Worker %f = load float, float* %ptr, align 4 291*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 292*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 293*9880d681SAndroid Build Coastguard Workerexit: 294*9880d681SAndroid Build Coastguard Worker ret void 295*9880d681SAndroid Build Coastguard Worker} 296*9880d681SAndroid Build Coastguard Worker 297*9880d681SAndroid Build Coastguard Worker; Multiplication by a non-zero constant propagates poison if there is 298*9880d681SAndroid Build Coastguard Worker; a nuw or nsw flag on the multiplication. 299*9880d681SAndroid Build Coastguard Workerdefine void @test-add-mul-propagates(float* %input, i32 %offset, i32 %numIterations) { 300*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-mul-propagates 301*9880d681SAndroid Build Coastguard Workerentry: 302*9880d681SAndroid Build Coastguard Worker br label %loop 303*9880d681SAndroid Build Coastguard Workerloop: 304*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 305*9880d681SAndroid Build Coastguard Worker 306*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 307*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nsw> 308*9880d681SAndroid Build Coastguard Worker %index32 = add nsw i32 %i, %offset 309*9880d681SAndroid Build Coastguard Worker 310*9880d681SAndroid Build Coastguard Worker %indexmul = mul nuw i32 %index32, 2 311*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i32 %indexmul 312*9880d681SAndroid Build Coastguard Worker %nexti = add nsw i32 %i, 1 313*9880d681SAndroid Build Coastguard Worker %f = load float, float* %ptr, align 4 314*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 315*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 316*9880d681SAndroid Build Coastguard Workerexit: 317*9880d681SAndroid Build Coastguard Worker ret void 318*9880d681SAndroid Build Coastguard Worker} 319*9880d681SAndroid Build Coastguard Worker 320*9880d681SAndroid Build Coastguard Worker; Multiplication by a non-constant should not propagate poison in the 321*9880d681SAndroid Build Coastguard Worker; very conservative approach used here. 322*9880d681SAndroid Build Coastguard Workerdefine void @test-add-mul-no-propagation(float* %input, i32 %offset, i32 %numIterations) { 323*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-mul-no-propagation 324*9880d681SAndroid Build Coastguard Workerentry: 325*9880d681SAndroid Build Coastguard Worker br label %loop 326*9880d681SAndroid Build Coastguard Workerloop: 327*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 328*9880d681SAndroid Build Coastguard Worker 329*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 330*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nw> 331*9880d681SAndroid Build Coastguard Worker %index32 = add nsw i32 %i, %offset 332*9880d681SAndroid Build Coastguard Worker 333*9880d681SAndroid Build Coastguard Worker %indexmul = mul nsw i32 %index32, %offset 334*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i32 %indexmul 335*9880d681SAndroid Build Coastguard Worker %nexti = add nsw i32 %i, 1 336*9880d681SAndroid Build Coastguard Worker %f = load float, float* %ptr, align 4 337*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 338*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 339*9880d681SAndroid Build Coastguard Workerexit: 340*9880d681SAndroid Build Coastguard Worker ret void 341*9880d681SAndroid Build Coastguard Worker} 342*9880d681SAndroid Build Coastguard Worker 343*9880d681SAndroid Build Coastguard Worker; Multiplication by a non-zero constant does not propagate poison 344*9880d681SAndroid Build Coastguard Worker; without a no-wrap flag. 345*9880d681SAndroid Build Coastguard Workerdefine void @test-add-mul-no-propagation2(float* %input, i32 %offset, i32 %numIterations) { 346*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-mul-no-propagation2 347*9880d681SAndroid Build Coastguard Workerentry: 348*9880d681SAndroid Build Coastguard Worker br label %loop 349*9880d681SAndroid Build Coastguard Workerloop: 350*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 351*9880d681SAndroid Build Coastguard Worker 352*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 353*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nw> 354*9880d681SAndroid Build Coastguard Worker %index32 = add nsw i32 %i, %offset 355*9880d681SAndroid Build Coastguard Worker 356*9880d681SAndroid Build Coastguard Worker %indexmul = mul i32 %index32, 2 357*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i32 %indexmul 358*9880d681SAndroid Build Coastguard Worker %nexti = add nsw i32 %i, 1 359*9880d681SAndroid Build Coastguard Worker %f = load float, float* %ptr, align 4 360*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 361*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 362*9880d681SAndroid Build Coastguard Workerexit: 363*9880d681SAndroid Build Coastguard Worker ret void 364*9880d681SAndroid Build Coastguard Worker} 365*9880d681SAndroid Build Coastguard Worker 366*9880d681SAndroid Build Coastguard Worker; Division by poison triggers UB. 367*9880d681SAndroid Build Coastguard Workerdefine void @test-add-div(float* %input, i32 %offset, i32 %numIterations) { 368*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-div 369*9880d681SAndroid Build Coastguard Workerentry: 370*9880d681SAndroid Build Coastguard Worker br label %loop 371*9880d681SAndroid Build Coastguard Workerloop: 372*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 373*9880d681SAndroid Build Coastguard Worker 374*9880d681SAndroid Build Coastguard Worker; CHECK: %j = 375*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nsw> 376*9880d681SAndroid Build Coastguard Worker %j = add nsw i32 %i, %offset 377*9880d681SAndroid Build Coastguard Worker 378*9880d681SAndroid Build Coastguard Worker %q = sdiv i32 %numIterations, %j 379*9880d681SAndroid Build Coastguard Worker %nexti = add nsw i32 %i, 1 380*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 381*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 382*9880d681SAndroid Build Coastguard Workerexit: 383*9880d681SAndroid Build Coastguard Worker ret void 384*9880d681SAndroid Build Coastguard Worker} 385*9880d681SAndroid Build Coastguard Worker 386*9880d681SAndroid Build Coastguard Worker; Remainder of poison by non-poison divisor does not trigger UB. 387*9880d681SAndroid Build Coastguard Workerdefine void @test-add-div2(float* %input, i32 %offset, i32 %numIterations) { 388*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-div2 389*9880d681SAndroid Build Coastguard Workerentry: 390*9880d681SAndroid Build Coastguard Worker br label %loop 391*9880d681SAndroid Build Coastguard Workerloop: 392*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 393*9880d681SAndroid Build Coastguard Worker 394*9880d681SAndroid Build Coastguard Worker; CHECK: %j = 395*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nw> 396*9880d681SAndroid Build Coastguard Worker %j = add nsw i32 %i, %offset 397*9880d681SAndroid Build Coastguard Worker 398*9880d681SAndroid Build Coastguard Worker %q = sdiv i32 %j, %numIterations 399*9880d681SAndroid Build Coastguard Worker %nexti = add nsw i32 %i, 1 400*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 401*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 402*9880d681SAndroid Build Coastguard Workerexit: 403*9880d681SAndroid Build Coastguard Worker ret void 404*9880d681SAndroid Build Coastguard Worker} 405*9880d681SAndroid Build Coastguard Worker 406*9880d681SAndroid Build Coastguard Worker; Store to poison address triggers UB. 407*9880d681SAndroid Build Coastguard Workerdefine void @test-add-store(float* %input, i32 %offset, i32 %numIterations) { 408*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-store 409*9880d681SAndroid Build Coastguard Workerentry: 410*9880d681SAndroid Build Coastguard Worker br label %loop 411*9880d681SAndroid Build Coastguard Workerloop: 412*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 413*9880d681SAndroid Build Coastguard Worker 414*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 415*9880d681SAndroid Build Coastguard Worker; CHECK: --> {%offset,+,1}<nsw> 416*9880d681SAndroid Build Coastguard Worker %index32 = add nsw i32 %i, %offset 417*9880d681SAndroid Build Coastguard Worker 418*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i32 %index32 419*9880d681SAndroid Build Coastguard Worker %nexti = add nsw i32 %i, 1 420*9880d681SAndroid Build Coastguard Worker store float 1.0, float* %ptr, align 4 421*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 422*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 423*9880d681SAndroid Build Coastguard Workerexit: 424*9880d681SAndroid Build Coastguard Worker ret void 425*9880d681SAndroid Build Coastguard Worker} 426*9880d681SAndroid Build Coastguard Worker 427*9880d681SAndroid Build Coastguard Worker; Three sequential adds where the middle add should have nsw. There is 428*9880d681SAndroid Build Coastguard Worker; a special case for sequential adds and this test covers that. We have to 429*9880d681SAndroid Build Coastguard Worker; put the final add first in the program since otherwise the special case 430*9880d681SAndroid Build Coastguard Worker; is not triggered, hence the strange basic block ordering. 431*9880d681SAndroid Build Coastguard Workerdefine void @test-add-twice(float* %input, i32 %offset, i32 %numIterations) { 432*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-add-twice 433*9880d681SAndroid Build Coastguard Workerentry: 434*9880d681SAndroid Build Coastguard Worker br label %loop 435*9880d681SAndroid Build Coastguard Workerloop2: 436*9880d681SAndroid Build Coastguard Worker; CHECK: %seq = 437*9880d681SAndroid Build Coastguard Worker; CHECK: --> {(2 + %offset),+,1}<nw> 438*9880d681SAndroid Build Coastguard Worker %seq = add nsw nuw i32 %index32, 1 439*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 440*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 441*9880d681SAndroid Build Coastguard Worker 442*9880d681SAndroid Build Coastguard Workerloop: 443*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] 444*9880d681SAndroid Build Coastguard Worker 445*9880d681SAndroid Build Coastguard Worker %j = add nsw i32 %i, 1 446*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 447*9880d681SAndroid Build Coastguard Worker; CHECK: --> {(1 + %offset)<nsw>,+,1}<nsw> 448*9880d681SAndroid Build Coastguard Worker %index32 = add nsw i32 %j, %offset 449*9880d681SAndroid Build Coastguard Worker 450*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i32 %index32 451*9880d681SAndroid Build Coastguard Worker %nexti = add nsw i32 %i, 1 452*9880d681SAndroid Build Coastguard Worker store float 1.0, float* %ptr, align 4 453*9880d681SAndroid Build Coastguard Worker br label %loop2 454*9880d681SAndroid Build Coastguard Workerexit: 455*9880d681SAndroid Build Coastguard Worker ret void 456*9880d681SAndroid Build Coastguard Worker} 457*9880d681SAndroid Build Coastguard Worker 458*9880d681SAndroid Build Coastguard Worker; Example where a mul should get the nsw flag, so that a sext can be 459*9880d681SAndroid Build Coastguard Worker; distributed over the mul. 460*9880d681SAndroid Build Coastguard Workerdefine void @test-mul-nsw(float* %input, i32 %stride, i32 %numIterations) { 461*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-mul-nsw 462*9880d681SAndroid Build Coastguard Workerentry: 463*9880d681SAndroid Build Coastguard Worker br label %loop 464*9880d681SAndroid Build Coastguard Workerloop: 465*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 466*9880d681SAndroid Build Coastguard Worker 467*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 468*9880d681SAndroid Build Coastguard Worker; CHECK: --> {0,+,%stride}<nsw> 469*9880d681SAndroid Build Coastguard Worker %index32 = mul nsw i32 %i, %stride 470*9880d681SAndroid Build Coastguard Worker 471*9880d681SAndroid Build Coastguard Worker; CHECK: %index64 = 472*9880d681SAndroid Build Coastguard Worker; CHECK: --> {0,+,(sext i32 %stride to i64)}<nsw> 473*9880d681SAndroid Build Coastguard Worker %index64 = sext i32 %index32 to i64 474*9880d681SAndroid Build Coastguard Worker 475*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i64 %index64 476*9880d681SAndroid Build Coastguard Worker %nexti = add nsw i32 %i, 1 477*9880d681SAndroid Build Coastguard Worker %f = load float, float* %ptr, align 4 478*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 479*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 480*9880d681SAndroid Build Coastguard Workerexit: 481*9880d681SAndroid Build Coastguard Worker ret void 482*9880d681SAndroid Build Coastguard Worker} 483*9880d681SAndroid Build Coastguard Worker 484*9880d681SAndroid Build Coastguard Worker; Example where a mul should get the nuw flag. 485*9880d681SAndroid Build Coastguard Workerdefine void @test-mul-nuw(float* %input, i32 %stride, i32 %numIterations) { 486*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-mul-nuw 487*9880d681SAndroid Build Coastguard Workerentry: 488*9880d681SAndroid Build Coastguard Worker br label %loop 489*9880d681SAndroid Build Coastguard Workerloop: 490*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 491*9880d681SAndroid Build Coastguard Worker 492*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 493*9880d681SAndroid Build Coastguard Worker; CHECK: --> {0,+,%stride}<nuw> 494*9880d681SAndroid Build Coastguard Worker %index32 = mul nuw i32 %i, %stride 495*9880d681SAndroid Build Coastguard Worker 496*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i32 %index32 497*9880d681SAndroid Build Coastguard Worker %nexti = add nuw i32 %i, 1 498*9880d681SAndroid Build Coastguard Worker %f = load float, float* %ptr, align 4 499*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 500*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 501*9880d681SAndroid Build Coastguard Worker 502*9880d681SAndroid Build Coastguard Workerexit: 503*9880d681SAndroid Build Coastguard Worker ret void 504*9880d681SAndroid Build Coastguard Worker} 505*9880d681SAndroid Build Coastguard Worker 506*9880d681SAndroid Build Coastguard Worker; Example where a shl should get the nsw flag, so that a sext can be 507*9880d681SAndroid Build Coastguard Worker; distributed over the shl. 508*9880d681SAndroid Build Coastguard Workerdefine void @test-shl-nsw(float* %input, i32 %start, i32 %numIterations) { 509*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-shl-nsw 510*9880d681SAndroid Build Coastguard Workerentry: 511*9880d681SAndroid Build Coastguard Worker br label %loop 512*9880d681SAndroid Build Coastguard Workerloop: 513*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop ], [ %start, %entry ] 514*9880d681SAndroid Build Coastguard Worker 515*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 516*9880d681SAndroid Build Coastguard Worker; CHECK: --> {(256 * %start),+,256}<nsw> 517*9880d681SAndroid Build Coastguard Worker %index32 = shl nsw i32 %i, 8 518*9880d681SAndroid Build Coastguard Worker 519*9880d681SAndroid Build Coastguard Worker; CHECK: %index64 = 520*9880d681SAndroid Build Coastguard Worker; CHECK: --> {(sext i32 (256 * %start) to i64),+,256}<nsw> 521*9880d681SAndroid Build Coastguard Worker %index64 = sext i32 %index32 to i64 522*9880d681SAndroid Build Coastguard Worker 523*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i64 %index64 524*9880d681SAndroid Build Coastguard Worker %nexti = add nsw i32 %i, 1 525*9880d681SAndroid Build Coastguard Worker %f = load float, float* %ptr, align 4 526*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 527*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 528*9880d681SAndroid Build Coastguard Workerexit: 529*9880d681SAndroid Build Coastguard Worker ret void 530*9880d681SAndroid Build Coastguard Worker} 531*9880d681SAndroid Build Coastguard Worker 532*9880d681SAndroid Build Coastguard Worker; Example where a shl should get the nuw flag. 533*9880d681SAndroid Build Coastguard Workerdefine void @test-shl-nuw(float* %input, i32 %numIterations) { 534*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-shl-nuw 535*9880d681SAndroid Build Coastguard Workerentry: 536*9880d681SAndroid Build Coastguard Worker br label %loop 537*9880d681SAndroid Build Coastguard Workerloop: 538*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 539*9880d681SAndroid Build Coastguard Worker 540*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 541*9880d681SAndroid Build Coastguard Worker; CHECK: --> {0,+,512}<nuw> 542*9880d681SAndroid Build Coastguard Worker %index32 = shl nuw i32 %i, 9 543*9880d681SAndroid Build Coastguard Worker 544*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i32 %index32 545*9880d681SAndroid Build Coastguard Worker %nexti = add nuw i32 %i, 1 546*9880d681SAndroid Build Coastguard Worker %f = load float, float* %ptr, align 4 547*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 548*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 549*9880d681SAndroid Build Coastguard Worker 550*9880d681SAndroid Build Coastguard Workerexit: 551*9880d681SAndroid Build Coastguard Worker ret void 552*9880d681SAndroid Build Coastguard Worker} 553*9880d681SAndroid Build Coastguard Worker 554*9880d681SAndroid Build Coastguard Worker; Example where a sub should *not* get the nsw flag, because of how 555*9880d681SAndroid Build Coastguard Worker; scalar evolution represents A - B as A + (-B) and -B can wrap even 556*9880d681SAndroid Build Coastguard Worker; in cases where A - B does not. 557*9880d681SAndroid Build Coastguard Workerdefine void @test-sub-no-nsw(float* %input, i32 %start, i32 %sub, i32 %numIterations) { 558*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-sub-no-nsw 559*9880d681SAndroid Build Coastguard Workerentry: 560*9880d681SAndroid Build Coastguard Worker br label %loop 561*9880d681SAndroid Build Coastguard Workerloop: 562*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop ], [ %start, %entry ] 563*9880d681SAndroid Build Coastguard Worker 564*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 565*9880d681SAndroid Build Coastguard Worker; CHECK: --> {((-1 * %sub) + %start),+,1}<nw> 566*9880d681SAndroid Build Coastguard Worker %index32 = sub nsw i32 %i, %sub 567*9880d681SAndroid Build Coastguard Worker %index64 = sext i32 %index32 to i64 568*9880d681SAndroid Build Coastguard Worker 569*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i64 %index64 570*9880d681SAndroid Build Coastguard Worker %nexti = add nsw i32 %i, 1 571*9880d681SAndroid Build Coastguard Worker %f = load float, float* %ptr, align 4 572*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 573*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 574*9880d681SAndroid Build Coastguard Workerexit: 575*9880d681SAndroid Build Coastguard Worker ret void 576*9880d681SAndroid Build Coastguard Worker} 577*9880d681SAndroid Build Coastguard Worker 578*9880d681SAndroid Build Coastguard Worker; Example where a sub should get the nsw flag as the RHS cannot be the 579*9880d681SAndroid Build Coastguard Worker; minimal signed value. 580*9880d681SAndroid Build Coastguard Workerdefine void @test-sub-nsw(float* %input, i32 %start, i32 %sub, i32 %numIterations) { 581*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-sub-nsw 582*9880d681SAndroid Build Coastguard Workerentry: 583*9880d681SAndroid Build Coastguard Worker %halfsub = ashr i32 %sub, 1 584*9880d681SAndroid Build Coastguard Worker br label %loop 585*9880d681SAndroid Build Coastguard Workerloop: 586*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop ], [ %start, %entry ] 587*9880d681SAndroid Build Coastguard Worker 588*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 589*9880d681SAndroid Build Coastguard Worker; CHECK: --> {((-1 * %halfsub)<nsw> + %start)<nsw>,+,1}<nsw> 590*9880d681SAndroid Build Coastguard Worker %index32 = sub nsw i32 %i, %halfsub 591*9880d681SAndroid Build Coastguard Worker %index64 = sext i32 %index32 to i64 592*9880d681SAndroid Build Coastguard Worker 593*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i64 %index64 594*9880d681SAndroid Build Coastguard Worker %nexti = add nsw i32 %i, 1 595*9880d681SAndroid Build Coastguard Worker %f = load float, float* %ptr, align 4 596*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 597*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 598*9880d681SAndroid Build Coastguard Workerexit: 599*9880d681SAndroid Build Coastguard Worker ret void 600*9880d681SAndroid Build Coastguard Worker} 601*9880d681SAndroid Build Coastguard Worker 602*9880d681SAndroid Build Coastguard Worker; Example where a sub should get the nsw flag, since the LHS is non-negative, 603*9880d681SAndroid Build Coastguard Worker; which implies that the RHS cannot be the minimal signed value. 604*9880d681SAndroid Build Coastguard Workerdefine void @test-sub-nsw-lhs-non-negative(float* %input, i32 %sub, i32 %numIterations) { 605*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-sub-nsw-lhs-non-negative 606*9880d681SAndroid Build Coastguard Workerentry: 607*9880d681SAndroid Build Coastguard Worker br label %loop 608*9880d681SAndroid Build Coastguard Workerloop: 609*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 610*9880d681SAndroid Build Coastguard Worker 611*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 612*9880d681SAndroid Build Coastguard Worker; CHECK: --> {(-1 * %sub),+,1}<nsw> 613*9880d681SAndroid Build Coastguard Worker %index32 = sub nsw i32 %i, %sub 614*9880d681SAndroid Build Coastguard Worker 615*9880d681SAndroid Build Coastguard Worker; CHECK: %index64 = 616*9880d681SAndroid Build Coastguard Worker; CHECK: --> {(sext i32 (-1 * %sub) to i64),+,1}<nsw> 617*9880d681SAndroid Build Coastguard Worker %index64 = sext i32 %index32 to i64 618*9880d681SAndroid Build Coastguard Worker 619*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i64 %index64 620*9880d681SAndroid Build Coastguard Worker %nexti = add nsw i32 %i, 1 621*9880d681SAndroid Build Coastguard Worker %f = load float, float* %ptr, align 4 622*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 623*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 624*9880d681SAndroid Build Coastguard Workerexit: 625*9880d681SAndroid Build Coastguard Worker ret void 626*9880d681SAndroid Build Coastguard Worker} 627*9880d681SAndroid Build Coastguard Worker 628*9880d681SAndroid Build Coastguard Worker; Two adds with a sub in the middle and the sub should have nsw. There is 629*9880d681SAndroid Build Coastguard Worker; a special case for sequential adds/subs and this test covers that. We have to 630*9880d681SAndroid Build Coastguard Worker; put the final add first in the program since otherwise the special case 631*9880d681SAndroid Build Coastguard Worker; is not triggered, hence the strange basic block ordering. 632*9880d681SAndroid Build Coastguard Workerdefine void @test-sub-with-add(float* %input, i32 %offset, i32 %numIterations) { 633*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test-sub-with-add 634*9880d681SAndroid Build Coastguard Workerentry: 635*9880d681SAndroid Build Coastguard Worker br label %loop 636*9880d681SAndroid Build Coastguard Workerloop2: 637*9880d681SAndroid Build Coastguard Worker; CHECK: %seq = 638*9880d681SAndroid Build Coastguard Worker; CHECK: --> {(2 + (-1 * %offset)),+,1}<nw> 639*9880d681SAndroid Build Coastguard Worker %seq = add nsw nuw i32 %index32, 1 640*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %nexti, %numIterations 641*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %exit, label %loop 642*9880d681SAndroid Build Coastguard Worker 643*9880d681SAndroid Build Coastguard Workerloop: 644*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] 645*9880d681SAndroid Build Coastguard Worker 646*9880d681SAndroid Build Coastguard Worker %j = add nsw i32 %i, 1 647*9880d681SAndroid Build Coastguard Worker; CHECK: %index32 = 648*9880d681SAndroid Build Coastguard Worker; CHECK: --> {(1 + (-1 * %offset))<nsw>,+,1}<nsw> 649*9880d681SAndroid Build Coastguard Worker %index32 = sub nsw i32 %j, %offset 650*9880d681SAndroid Build Coastguard Worker 651*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr inbounds float, float* %input, i32 %index32 652*9880d681SAndroid Build Coastguard Worker %nexti = add nsw i32 %i, 1 653*9880d681SAndroid Build Coastguard Worker store float 1.0, float* %ptr, align 4 654*9880d681SAndroid Build Coastguard Worker br label %loop2 655*9880d681SAndroid Build Coastguard Workerexit: 656*9880d681SAndroid Build Coastguard Worker ret void 657*9880d681SAndroid Build Coastguard Worker} 658*9880d681SAndroid Build Coastguard Worker 659*9880d681SAndroid Build Coastguard Worker 660*9880d681SAndroid Build Coastguard Worker; Subtraction of two recurrences. The addition in the SCEV that this 661*9880d681SAndroid Build Coastguard Worker; maps to is NSW, but the negation of the RHS does not since that 662*9880d681SAndroid Build Coastguard Worker; recurrence could be the most negative representable value. 663*9880d681SAndroid Build Coastguard Workerdefine void @subrecurrences(i32 %outer_l, i32 %inner_l, i32 %val) { 664*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @subrecurrences 665*9880d681SAndroid Build Coastguard Worker entry: 666*9880d681SAndroid Build Coastguard Worker br label %outer 667*9880d681SAndroid Build Coastguard Worker 668*9880d681SAndroid Build Coastguard Workerouter: 669*9880d681SAndroid Build Coastguard Worker %o_idx = phi i32 [ 0, %entry ], [ %o_idx.inc, %outer.be ] 670*9880d681SAndroid Build Coastguard Worker %o_idx.inc = add nsw i32 %o_idx, 1 671*9880d681SAndroid Build Coastguard Worker %cond = icmp eq i32 %o_idx, %val 672*9880d681SAndroid Build Coastguard Worker br i1 %cond, label %inner, label %outer.be 673*9880d681SAndroid Build Coastguard Worker 674*9880d681SAndroid Build Coastguard Workerinner: 675*9880d681SAndroid Build Coastguard Worker %i_idx = phi i32 [ 0, %outer ], [ %i_idx.inc, %inner ] 676*9880d681SAndroid Build Coastguard Worker %i_idx.inc = add nsw i32 %i_idx, 1 677*9880d681SAndroid Build Coastguard Worker; CHECK: %v = 678*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {{[{][{]}}-1,+,-1}<nw><%outer>,+,1}<nsw><%inner> 679*9880d681SAndroid Build Coastguard Worker %v = sub nsw i32 %i_idx, %o_idx.inc 680*9880d681SAndroid Build Coastguard Worker %forub = udiv i32 1, %v 681*9880d681SAndroid Build Coastguard Worker %cond2 = icmp eq i32 %i_idx, %inner_l 682*9880d681SAndroid Build Coastguard Worker br i1 %cond2, label %outer.be, label %inner 683*9880d681SAndroid Build Coastguard Worker 684*9880d681SAndroid Build Coastguard Workerouter.be: 685*9880d681SAndroid Build Coastguard Worker %cond3 = icmp eq i32 %o_idx, %outer_l 686*9880d681SAndroid Build Coastguard Worker br i1 %cond3, label %exit, label %outer 687*9880d681SAndroid Build Coastguard Worker 688*9880d681SAndroid Build Coastguard Workerexit: 689*9880d681SAndroid Build Coastguard Worker ret void 690*9880d681SAndroid Build Coastguard Worker} 691