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