Home | History | Annotate | Download | only in ScalarEvolution
      1 ; RUN: opt -analyze -scalar-evolution < %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_0(i8* %a) {
      7 ; CHECK-LABEL: Classifying expressions for: @f_sadd_0
      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 ; CHECK:  %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
     16 ; CHECK-NEXT:  -->  {0,+,1}<nuw><nsw><%for.body> U: [0,16) S: [0,16)
     17 
     18   %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
     19   %idxprom = sext i32 %i.04 to i64
     20   %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
     21   store i8 0, i8* %arrayidx, align 1
     22   %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
     23   %tmp1 = extractvalue { i32, i1 } %tmp0, 1
     24   br i1 %tmp1, 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   %tmp2 = extractvalue { i32, i1 } %tmp0, 0
     32   %cmp = icmp slt i32 %tmp2, 16
     33   br i1 %cmp, label %for.body, label %for.cond.cleanup
     34 ; CHECK: Loop %for.body: max backedge-taken count is 15
     35 }
     36 
     37 define void @f_sadd_1(i8* %a) {
     38 ; CHECK-LABEL: Classifying expressions for: @f_sadd_1
     39 entry:
     40   br label %for.body
     41 
     42 for.cond.cleanup:                                 ; preds = %cont
     43   ret void
     44 
     45 for.body:                                         ; preds = %entry, %cont
     46 ; CHECK:  %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
     47 ; CHECK-NEXT:  -->  {0,+,1}<%for.body> U: [0,16) S: [0,16)
     48 
     49 ; SCEV can prove <nsw> for the above induction variable; but it does
     50 ; not bother so before it sees the sext below since it is not a 100%
     51 ; obvious.
     52 
     53   %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
     54   %idxprom = sext i32 %i.04 to i64
     55   %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
     56   store i8 0, i8* %arrayidx, align 1
     57   %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
     58   %tmp1 = extractvalue { i32, i1 } %tmp0, 1
     59   br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
     60 
     61 trap:                                             ; preds = %for.body
     62 
     63   br label %cont
     64 
     65 cont:                                             ; preds = %for.body
     66   %tmp2 = extractvalue { i32, i1 } %tmp0, 0
     67   %cmp = icmp slt i32 %tmp2, 16
     68   br i1 %cmp, label %for.body, label %for.cond.cleanup
     69 ; CHECK: Loop %for.body: max backedge-taken count is 15
     70 }
     71 
     72 define void @f_sadd_2(i8* %a, i1* %c) {
     73 ; CHECK-LABEL: Classifying expressions for: @f_sadd_2
     74 entry:
     75   br label %for.body
     76 
     77 for.cond.cleanup:                                 ; preds = %cont
     78   ret void
     79 
     80 for.body:                                         ; preds = %entry, %cont
     81 ; CHECK:  %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
     82 ; CHECK-NEXT:  -->  {0,+,1}<%for.body>
     83 
     84   %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
     85   %idxprom = sext i32 %i.04 to i64
     86   %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
     87   store i8 0, i8* %arrayidx, align 1
     88   %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
     89   %tmp1 = extractvalue { i32, i1 } %tmp0, 1
     90   br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
     91 
     92 trap:                                             ; preds = %for.body
     93 
     94   br label %cont
     95 
     96 cont:                                             ; preds = %for.body
     97   %tmp2 = extractvalue { i32, i1 } %tmp0, 0
     98   %cond = load volatile i1, i1* %c
     99   br i1 %cond, label %for.body, label %for.cond.cleanup
    100 }
    101 
    102 define void @f_sadd_3(i8* %a, i1* %c) {
    103 ; CHECK-LABEL: Classifying expressions for: @f_sadd_3
    104 entry:
    105   br label %for.body
    106 
    107 for.cond.cleanup:                                 ; preds = %cont
    108   ret void
    109 
    110 for.body:                                         ; preds = %entry, %cont
    111 ; CHECK:  %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %for.body ]
    112 ; CHECK-NEXT:  -->  {0,+,1}<nuw><nsw><%for.body>
    113 
    114   %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %for.body ]
    115   %idxprom = sext i32 %i.04 to i64
    116   %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
    117   store i8 0, i8* %arrayidx, align 1
    118   %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
    119   %tmp1 = extractvalue { i32, i1 } %tmp0, 1
    120   %tmp2 = extractvalue { i32, i1 } %tmp0, 0
    121   br i1 %tmp1, label %trap, label %for.body, !nosanitize !{}
    122 
    123 trap:                                             ; preds = %for.body
    124   tail call void @llvm.trap() #2, !nosanitize !{}
    125   unreachable, !nosanitize !{}
    126 }
    127 
    128 define void @f_sadd_4(i8* %a, i1* %c) {
    129 ; CHECK-LABEL: Classifying expressions for: @f_sadd_4
    130 entry:
    131   br label %for.body
    132 
    133 for.cond.cleanup:                                 ; preds = %cont
    134   ret void
    135 
    136 for.body:                                         ; preds = %entry, %cont
    137 ; CHECK:  %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %merge ]
    138 ; CHECK-NEXT:  -->  {0,+,1}<nuw><nsw><%for.body>
    139 
    140   %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %merge ]
    141   %idxprom = sext i32 %i.04 to i64
    142   %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
    143   store i8 0, i8* %arrayidx, align 1
    144   %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
    145   %tmp1 = extractvalue { i32, i1 } %tmp0, 1
    146   %tmp2 = extractvalue { i32, i1 } %tmp0, 0
    147   br i1 %tmp1, label %notrap, label %merge
    148 
    149 notrap:
    150   br label %merge
    151 
    152 merge:
    153   %tmp3 = extractvalue { i32, i1 } %tmp0, 1
    154   br i1 %tmp3, label %trap, label %for.body, !nosanitize !{}
    155 
    156 trap:                                             ; preds = %for.body
    157   tail call void @llvm.trap() #2, !nosanitize !{}
    158   unreachable, !nosanitize !{}
    159 }
    160 
    161 define void @f_sadd_may_overflow(i8* %a, i1* %c) {
    162 ; CHECK-LABEL: Classifying expressions for: @f_sadd_may_overflow
    163 entry:
    164   br label %for.body
    165 
    166 for.cond.cleanup:                                 ; preds = %cont
    167   ret void
    168 
    169 for.body:                                         ; preds = %entry, %cont
    170 ; CHECK:  %i.04 = phi i32 [ 0, %entry ], [ %tmp1, %cont ]
    171 ; CHECK-NEXT:  -->  {0,+,1}<%for.body> U: full-set S: full-set
    172 
    173   %i.04 = phi i32 [ 0, %entry ], [ %tmp1, %cont ]
    174   %idxprom = sext i32 %i.04 to i64
    175   %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
    176   store i8 0, i8* %arrayidx, align 1
    177   %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
    178   %cond1 = load volatile i1, i1* %c
    179   br i1 %cond1, label %trap, label %cont, !nosanitize !{}
    180 
    181 trap:                                             ; preds = %for.body
    182   tail call void @llvm.trap() #2, !nosanitize !{}
    183   unreachable, !nosanitize !{}
    184 
    185 cont:                                             ; preds = %for.body
    186   %tmp1 = extractvalue { i32, i1 } %tmp0, 0
    187   %cond = load volatile i1, i1* %c
    188   br i1 %cond, label %for.body, label %for.cond.cleanup
    189 }
    190 
    191 define void @f_uadd(i8* %a) {
    192 ; CHECK-LABEL: Classifying expressions for: @f_uadd
    193 entry:
    194   br label %for.body
    195 
    196 for.cond.cleanup:                                 ; preds = %cont
    197   ret void
    198 
    199 for.body:                                         ; preds = %entry, %cont
    200 ; CHECK:  %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
    201 ; CHECK-NEXT:  -->  {0,+,1}<nuw><%for.body> U: [0,16) S: [0,16)
    202 
    203   %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
    204   %idxprom = sext i32 %i.04 to i64
    205   %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
    206   store i8 0, i8* %arrayidx, align 1
    207   %tmp0 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %i.04, i32 1)
    208   %tmp1 = extractvalue { i32, i1 } %tmp0, 1
    209   br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
    210 
    211 trap:                                             ; preds = %for.body
    212   tail call void @llvm.trap(), !nosanitize !{}
    213   unreachable, !nosanitize !{}
    214 
    215 cont:                                             ; preds = %for.body
    216   %tmp2 = extractvalue { i32, i1 } %tmp0, 0
    217   %cmp = icmp slt i32 %tmp2, 16
    218   br i1 %cmp, label %for.body, label %for.cond.cleanup
    219 ; CHECK: Loop %for.body: max backedge-taken count is 15
    220 }
    221 
    222 define void @f_ssub(i8* nocapture %a) {
    223 ; CHECK-LABEL: Classifying expressions for: @f_ssub
    224 entry:
    225   br label %for.body
    226 
    227 for.cond.cleanup:                                 ; preds = %cont
    228   ret void
    229 
    230 for.body:                                         ; preds = %entry, %cont
    231 ; CHECK:  %i.04 = phi i32 [ 15, %entry ], [ %tmp2, %cont ]
    232 ; CHECK-NEXT:  -->  {15,+,-1}<%for.body> U: [0,16) S: [0,16)
    233 
    234   %i.04 = phi i32 [ 15, %entry ], [ %tmp2, %cont ]
    235   %idxprom = sext i32 %i.04 to i64
    236   %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
    237   store i8 0, i8* %arrayidx, align 1
    238   %tmp0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %i.04, i32 1)
    239   %tmp1 = extractvalue { i32, i1 } %tmp0, 1
    240   br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
    241 
    242 trap:                                             ; preds = %for.body
    243   tail call void @llvm.trap(), !nosanitize !{}
    244   unreachable, !nosanitize !{}
    245 
    246 cont:                                             ; preds = %for.body
    247   %tmp2 = extractvalue { i32, i1 } %tmp0, 0
    248   %cmp = icmp sgt i32 %tmp2, -1
    249   br i1 %cmp, label %for.body, label %for.cond.cleanup
    250 ; CHECK: Loop %for.body: max backedge-taken count is 15
    251 }
    252 
    253 define void @f_usub(i8* nocapture %a) {
    254 ; CHECK-LABEL: Classifying expressions for: @f_usub
    255 entry:
    256   br label %for.body
    257 
    258 for.cond.cleanup:                                 ; preds = %cont
    259   ret void
    260 
    261 for.body:                                         ; preds = %entry, %cont
    262 ; CHECK:  %i.04 = phi i32 [ 15, %entry ], [ %tmp2, %cont ]
    263 ; CHECK-NEXT:  -->  {15,+,-1}<%for.body> U: [0,16) S: [0,16)
    264 
    265   %i.04 = phi i32 [ 15, %entry ], [ %tmp2, %cont ]
    266   %idxprom = sext i32 %i.04 to i64
    267   %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
    268   store i8 0, i8* %arrayidx, align 1
    269   %tmp0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %i.04, i32 1)
    270   %tmp1 = extractvalue { i32, i1 } %tmp0, 1
    271   br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
    272 
    273 trap:                                             ; preds = %for.body
    274   tail call void @llvm.trap(), !nosanitize !{}
    275   unreachable, !nosanitize !{}
    276 
    277 cont:                                             ; preds = %for.body
    278   %tmp2 = extractvalue { i32, i1 } %tmp0, 0
    279   %cmp = icmp sgt i32 %tmp2, -1
    280   br i1 %cmp, label %for.body, label %for.cond.cleanup
    281 ; CHECK: Loop %for.body: max backedge-taken count is 15
    282 }
    283 
    284 define i32 @f_smul(i32 %val_a, i32 %val_b) {
    285 ; CHECK-LABEL: Classifying expressions for: @f_smul
    286   %agg = tail call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %val_a, i32 %val_b)
    287 ; CHECK:   %mul = extractvalue { i32, i1 } %agg, 0
    288 ; CHECK-NEXT:  -->  (%val_a * %val_b) U: full-set S: full-set
    289   %mul = extractvalue { i32, i1 } %agg, 0
    290   ret i32 %mul
    291 }
    292 
    293 define i32 @f_umul(i32 %val_a, i32 %val_b) {
    294 ; CHECK-LABEL: Classifying expressions for: @f_umul
    295   %agg = tail call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %val_a, i32 %val_b)
    296 ; CHECK:   %mul = extractvalue { i32, i1 } %agg, 0
    297 ; CHECK-NEXT:  -->  (%val_a * %val_b) U: full-set S: full-set
    298   %mul = extractvalue { i32, i1 } %agg, 0
    299   ret i32 %mul
    300 }
    301 
    302 declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
    303 declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
    304 declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
    305 declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
    306 declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
    307 declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
    308 
    309 declare void @llvm.trap() #2
    310