1*9880d681SAndroid Build Coastguard Worker; RUN: opt -S -indvars < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 4*9880d681SAndroid Build Coastguard Workertarget triple = "x86_64-unknown-linux-gnu" 5*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Workerdefine void @f_sadd(i8* %a) { 7*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_sadd( 8*9880d681SAndroid Build Coastguard Workerentry: 9*9880d681SAndroid Build Coastguard Worker br label %for.body 10*9880d681SAndroid Build Coastguard Worker 11*9880d681SAndroid Build Coastguard Workerfor.cond.cleanup: ; preds = %cont 12*9880d681SAndroid Build Coastguard Worker ret void 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %entry, %cont 15*9880d681SAndroid Build Coastguard Worker %i.04 = phi i32 [ 0, %entry ], [ %2, %cont ] 16*9880d681SAndroid Build Coastguard Worker %idxprom = sext i32 %i.04 to i64 17*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom 18*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %arrayidx, align 1 19*9880d681SAndroid Build Coastguard Worker %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1) 20*9880d681SAndroid Build Coastguard Worker %1 = extractvalue { i32, i1 } %0, 1 21*9880d681SAndroid Build Coastguard Worker; CHECK: for.body: 22*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @llvm.sadd.with.overflow 23*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 false, label %trap, label %cont, !nosanitize !0 24*9880d681SAndroid Build Coastguard Worker br i1 %1, label %trap, label %cont, !nosanitize !{} 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Workertrap: ; preds = %for.body 27*9880d681SAndroid Build Coastguard Worker tail call void @llvm.trap() #2, !nosanitize !{} 28*9880d681SAndroid Build Coastguard Worker unreachable, !nosanitize !{} 29*9880d681SAndroid Build Coastguard Worker 30*9880d681SAndroid Build Coastguard Workercont: ; preds = %for.body 31*9880d681SAndroid Build Coastguard Worker %2 = extractvalue { i32, i1 } %0, 0 32*9880d681SAndroid Build Coastguard Worker %cmp = icmp slt i32 %2, 16 33*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %for.body, label %for.cond.cleanup 34*9880d681SAndroid Build Coastguard Worker} 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Workerdefine void @f_uadd(i8* %a) { 37*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_uadd( 38*9880d681SAndroid Build Coastguard Workerentry: 39*9880d681SAndroid Build Coastguard Worker br label %for.body 40*9880d681SAndroid Build Coastguard Worker 41*9880d681SAndroid Build Coastguard Workerfor.cond.cleanup: ; preds = %cont 42*9880d681SAndroid Build Coastguard Worker ret void 43*9880d681SAndroid Build Coastguard Worker 44*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %entry, %cont 45*9880d681SAndroid Build Coastguard Worker %i.04 = phi i32 [ 0, %entry ], [ %2, %cont ] 46*9880d681SAndroid Build Coastguard Worker %idxprom = sext i32 %i.04 to i64 47*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom 48*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %arrayidx, align 1 49*9880d681SAndroid Build Coastguard Worker %0 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %i.04, i32 1) 50*9880d681SAndroid Build Coastguard Worker %1 = extractvalue { i32, i1 } %0, 1 51*9880d681SAndroid Build Coastguard Worker; CHECK: for.body: 52*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @llvm.uadd.with.overflow 53*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 false, label %trap, label %cont, !nosanitize !0 54*9880d681SAndroid Build Coastguard Worker br i1 %1, label %trap, label %cont, !nosanitize !{} 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Workertrap: ; preds = %for.body 57*9880d681SAndroid Build Coastguard Worker tail call void @llvm.trap(), !nosanitize !{} 58*9880d681SAndroid Build Coastguard Worker unreachable, !nosanitize !{} 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Workercont: ; preds = %for.body 61*9880d681SAndroid Build Coastguard Worker %2 = extractvalue { i32, i1 } %0, 0 62*9880d681SAndroid Build Coastguard Worker %cmp = icmp slt i32 %2, 16 63*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %for.body, label %for.cond.cleanup 64*9880d681SAndroid Build Coastguard Worker} 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Workerdefine void @f_ssub(i8* nocapture %a) { 67*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_ssub( 68*9880d681SAndroid Build Coastguard Workerentry: 69*9880d681SAndroid Build Coastguard Worker br label %for.body 70*9880d681SAndroid Build Coastguard Worker 71*9880d681SAndroid Build Coastguard Workerfor.cond.cleanup: ; preds = %cont 72*9880d681SAndroid Build Coastguard Worker ret void 73*9880d681SAndroid Build Coastguard Worker 74*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %entry, %cont 75*9880d681SAndroid Build Coastguard Worker %i.04 = phi i32 [ 15, %entry ], [ %2, %cont ] 76*9880d681SAndroid Build Coastguard Worker %idxprom = sext i32 %i.04 to i64 77*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom 78*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %arrayidx, align 1 79*9880d681SAndroid Build Coastguard Worker %0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %i.04, i32 1) 80*9880d681SAndroid Build Coastguard Worker %1 = extractvalue { i32, i1 } %0, 1 81*9880d681SAndroid Build Coastguard Worker; CHECK: for.body: 82*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @llvm.ssub.with.overflow.i32 83*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 false, label %trap, label %cont, !nosanitize !0 84*9880d681SAndroid Build Coastguard Worker br i1 %1, label %trap, label %cont, !nosanitize !{} 85*9880d681SAndroid Build Coastguard Worker 86*9880d681SAndroid Build Coastguard Workertrap: ; preds = %for.body 87*9880d681SAndroid Build Coastguard Worker tail call void @llvm.trap(), !nosanitize !{} 88*9880d681SAndroid Build Coastguard Worker unreachable, !nosanitize !{} 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Workercont: ; preds = %for.body 91*9880d681SAndroid Build Coastguard Worker %2 = extractvalue { i32, i1 } %0, 0 92*9880d681SAndroid Build Coastguard Worker %cmp = icmp sgt i32 %2, -1 93*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %for.body, label %for.cond.cleanup 94*9880d681SAndroid Build Coastguard Worker} 95*9880d681SAndroid Build Coastguard Worker 96*9880d681SAndroid Build Coastguard Workerdefine void @f_usub(i8* nocapture %a) { 97*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_usub( 98*9880d681SAndroid Build Coastguard Workerentry: 99*9880d681SAndroid Build Coastguard Worker br label %for.body 100*9880d681SAndroid Build Coastguard Worker 101*9880d681SAndroid Build Coastguard Workerfor.cond.cleanup: ; preds = %cont 102*9880d681SAndroid Build Coastguard Worker ret void 103*9880d681SAndroid Build Coastguard Worker 104*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %entry, %cont 105*9880d681SAndroid Build Coastguard Worker %i.04 = phi i32 [ 15, %entry ], [ %2, %cont ] 106*9880d681SAndroid Build Coastguard Worker %idxprom = sext i32 %i.04 to i64 107*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom 108*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %arrayidx, align 1 109*9880d681SAndroid Build Coastguard Worker %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %i.04, i32 1) 110*9880d681SAndroid Build Coastguard Worker %1 = extractvalue { i32, i1 } %0, 1 111*9880d681SAndroid Build Coastguard Worker 112*9880d681SAndroid Build Coastguard Worker; It is theoretically possible to prove this, but SCEV cannot 113*9880d681SAndroid Build Coastguard Worker; represent non-unsigned-wrapping subtraction operations. 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Worker; CHECK: for.body: 116*9880d681SAndroid Build Coastguard Worker; CHECK: [[COND:%[^ ]+]] = extractvalue { i32, i1 } %1, 1 117*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br i1 [[COND]], label %trap, label %cont, !nosanitize !0 118*9880d681SAndroid Build Coastguard Worker br i1 %1, label %trap, label %cont, !nosanitize !{} 119*9880d681SAndroid Build Coastguard Worker 120*9880d681SAndroid Build Coastguard Workertrap: ; preds = %for.body 121*9880d681SAndroid Build Coastguard Worker tail call void @llvm.trap(), !nosanitize !{} 122*9880d681SAndroid Build Coastguard Worker unreachable, !nosanitize !{} 123*9880d681SAndroid Build Coastguard Worker 124*9880d681SAndroid Build Coastguard Workercont: ; preds = %for.body 125*9880d681SAndroid Build Coastguard Worker %2 = extractvalue { i32, i1 } %0, 0 126*9880d681SAndroid Build Coastguard Worker %cmp = icmp sgt i32 %2, -1 127*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %for.body, label %for.cond.cleanup 128*9880d681SAndroid Build Coastguard Worker} 129*9880d681SAndroid Build Coastguard Worker 130*9880d681SAndroid Build Coastguard Workerdeclare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone 131*9880d681SAndroid Build Coastguard Workerdeclare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone 132*9880d681SAndroid Build Coastguard Workerdeclare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone 133*9880d681SAndroid Build Coastguard Workerdeclare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone 134*9880d681SAndroid Build Coastguard Workerdeclare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone 135*9880d681SAndroid Build Coastguard Workerdeclare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone 136*9880d681SAndroid Build Coastguard Worker 137*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.trap() #2 138