Home | History | Annotate | Download | only in BoundsChecking
      1 ; RUN: opt < %s -bounds-checking -S | FileCheck %s
      2 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
      3 
      4 ; CHECK-LABEL: @sumSize
      5 define dso_local i32 @sumSize(i32 %n) {
      6 entry:
      7   %foo = alloca [1000 x i32], align 16
      8   %0 = bitcast [1000 x i32]* %foo to i8*
      9   call void @llvm.lifetime.start.p0i8(i64 4000, i8* nonnull %0)
     10   %arraydecay = getelementptr inbounds [1000 x i32], [1000 x i32]* %foo, i64 0, i64 0
     11   call void @fill(i32* nonnull %arraydecay, i32 %n)
     12   br label %for.body.i
     13 
     14 for.body.i:                                       ; preds = %for.body.i, %entry
     15   %indvars.iv.i = phi i64 [ 0, %entry ], [ %indvars.iv.next.i, %for.body.i ]
     16   %sum.07.i = phi i32 [ 0, %entry ], [ %add.i, %for.body.i ]
     17   %arrayidx.i = getelementptr inbounds [1000 x i32], [1000 x i32]* %foo, i64 0, i64 %indvars.iv.i
     18 ; CHECK-NOT: trap
     19   %1 = load i32, i32* %arrayidx.i, align 4
     20   %add.i = add nsw i32 %1, %sum.07.i
     21   %indvars.iv.next.i = add nuw nsw i64 %indvars.iv.i, 1
     22   %exitcond.i = icmp eq i64 %indvars.iv.next.i, 1000
     23   br i1 %exitcond.i, label %accumulate.exit, label %for.body.i
     24 
     25 accumulate.exit:                                  ; preds = %for.body.i
     26   call void @llvm.lifetime.end.p0i8(i64 4000, i8* nonnull %0)
     27   ret i32 %add.i
     28 }
     29 
     30 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
     31 
     32 declare dso_local void @fill(i32*, i32)
     33 
     34 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
     35 
     36 ; CHECK-LABEL: @sumSizePlusOne
     37 define dso_local i32 @sumSizePlusOne(i32 %n) {
     38 entry:
     39   %foo = alloca [1000 x i32], align 16
     40   %0 = bitcast [1000 x i32]* %foo to i8*
     41   call void @llvm.lifetime.start.p0i8(i64 4000, i8* nonnull %0)
     42   %arraydecay = getelementptr inbounds [1000 x i32], [1000 x i32]* %foo, i64 0, i64 0
     43   call void @fill(i32* nonnull %arraydecay, i32 %n)
     44   br label %for.body.i
     45 
     46 for.body.i:                                       ; preds = %for.body.i, %entry
     47   %indvars.iv.i = phi i64 [ 0, %entry ], [ %indvars.iv.next.i, %for.body.i ]
     48   %sum.01.i = phi i32 [ 0, %entry ], [ %add.i, %for.body.i ]
     49   %arrayidx.i = getelementptr inbounds [1000 x i32], [1000 x i32]* %foo, i64 0, i64 %indvars.iv.i
     50 ; CHECK: mul i64 {{.*}}, 4
     51 ; CHECK: sub i64 4000, %
     52 ; CHECK-NEXT: icmp ult i64 {{.*}}, 4
     53 ; CHECK-NEXT: or i1
     54 ; CHECK: trap
     55   %1 = load i32, i32* %arrayidx.i, align 4
     56   %add.i = add nsw i32 %1, %sum.01.i
     57   %indvars.iv.next.i = add nuw nsw i64 %indvars.iv.i, 1
     58   %exitcond.i = icmp eq i64 %indvars.iv.next.i, 1001
     59   br i1 %exitcond.i, label %accumulate.exit, label %for.body.i
     60 
     61 accumulate.exit:                                  ; preds = %for.body.i
     62   call void @llvm.lifetime.end.p0i8(i64 4000, i8* nonnull %0)
     63   ret i32 %add.i
     64 }
     65 
     66 ; CHECK-LABEL: @sumLarger
     67 define dso_local i32 @sumLarger(i32 %n) {
     68 entry:
     69   %foo = alloca [1000 x i32], align 16
     70   %0 = bitcast [1000 x i32]* %foo to i8*
     71   call void @llvm.lifetime.start.p0i8(i64 4000, i8* nonnull %0)
     72   %arraydecay = getelementptr inbounds [1000 x i32], [1000 x i32]* %foo, i64 0, i64 0
     73   call void @fill(i32* nonnull %arraydecay, i32 %n)
     74   br label %for.body.i
     75 
     76 for.body.i:                                       ; preds = %for.body.i, %entry
     77   %indvars.iv.i = phi i64 [ 0, %entry ], [ %indvars.iv.next.i, %for.body.i ]
     78   %sum.07.i = phi i32 [ 0, %entry ], [ %add.i, %for.body.i ]
     79   %arrayidx.i = getelementptr inbounds [1000 x i32], [1000 x i32]* %foo, i64 0, i64 %indvars.iv.i
     80 ; CHECK: mul i64 {{.*}}, 4
     81 ; CHECK: sub i64 4000, %
     82 ; CHECK-NEXT: icmp ult i64 4000, %
     83 ; CHECK-NEXT: icmp ult i64 {{.*}}, 4
     84 ; CHECK-NEXT: or i1
     85 ; CHECK: trap
     86   %1 = load i32, i32* %arrayidx.i, align 4
     87   %add.i = add nsw i32 %1, %sum.07.i
     88   %indvars.iv.next.i = add nuw nsw i64 %indvars.iv.i, 1
     89   %exitcond.i = icmp eq i64 %indvars.iv.next.i, 2000
     90   br i1 %exitcond.i, label %accumulate.exit, label %for.body.i
     91 
     92 accumulate.exit:                                  ; preds = %for.body.i
     93   call void @llvm.lifetime.end.p0i8(i64 4000, i8* nonnull %0)
     94   ret i32 %add.i
     95 }
     96 
     97 ; CHECK-LABEL: @sumUnknown
     98 define dso_local i32 @sumUnknown(i32 %n) {
     99 entry:
    100   %foo = alloca [1000 x i32], align 16
    101   %0 = bitcast [1000 x i32]* %foo to i8*
    102   call void @llvm.lifetime.start.p0i8(i64 4000, i8* nonnull %0)
    103   %arraydecay = getelementptr inbounds [1000 x i32], [1000 x i32]* %foo, i64 0, i64 0
    104   call void @fill(i32* nonnull %arraydecay, i32 %n)
    105   %cmp6.i = icmp eq i32 %n, 0
    106   br i1 %cmp6.i, label %accumulate.exit, label %for.body.preheader.i
    107 
    108 for.body.preheader.i:                             ; preds = %entry
    109   %wide.trip.count.i = zext i32 %n to i64
    110   br label %for.body.i
    111 
    112 for.body.i:                                       ; preds = %for.body.i, %for.body.preheader.i
    113   %indvars.iv.i = phi i64 [ 0, %for.body.preheader.i ], [ %indvars.iv.next.i, %for.body.i ]
    114   %sum.07.i = phi i32 [ 0, %for.body.preheader.i ], [ %add.i, %for.body.i ]
    115   %arrayidx.i = getelementptr inbounds [1000 x i32], [1000 x i32]* %foo, i64 0, i64 %indvars.iv.i
    116 ; CHECK: mul i64 {{.*}}, 4
    117 ; CHECK: sub i64 4000, %
    118 ; CHECK-NEXT: icmp ult i64 4000, %
    119 ; CHECK-NEXT: icmp ult i64 {{.*}}, 4
    120 ; CHECK-NEXT: or i1
    121 ; CHECK: trap
    122   %1 = load i32, i32* %arrayidx.i, align 4
    123   %add.i = add nsw i32 %1, %sum.07.i
    124   %indvars.iv.next.i = add nuw nsw i64 %indvars.iv.i, 1
    125   %exitcond.i = icmp eq i64 %indvars.iv.next.i, %wide.trip.count.i
    126   br i1 %exitcond.i, label %accumulate.exit, label %for.body.i
    127 
    128 accumulate.exit:                                  ; preds = %for.body.i, %entry
    129   %sum.0.lcssa.i = phi i32 [ 0, %entry ], [ %add.i, %for.body.i ]
    130   call void @llvm.lifetime.end.p0i8(i64 4000, i8* nonnull %0)
    131   ret i32 %sum.0.lcssa.i
    132 }
    133 
    134 ; CHECK-LABEL: @twoDimSize
    135 define dso_local i32 @twoDimSize(i32 %n) {
    136 entry:
    137   %foo = alloca [2 x [2 x i32]], align 16
    138   %0 = bitcast [2 x [2 x i32]]* %foo to i8*
    139   call void @llvm.lifetime.start.p0i8(i64 16, i8* nonnull %0)
    140   %arraydecay = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %foo, i64 0, i64 0, i64 0
    141   call void @fill(i32* nonnull %arraydecay, i32 %n)
    142   br label %for.cond1.preheader
    143 
    144 for.cond1.preheader:                              ; preds = %for.cond.cleanup3, %entry
    145   %indvars.iv23 = phi i64 [ 0, %entry ], [ %indvars.iv.next24, %for.cond.cleanup3 ]
    146   %sum.021 = phi i32 [ 0, %entry ], [ %add, %for.cond.cleanup3 ]
    147   br label %for.body4
    148 
    149 for.cond.cleanup:                                 ; preds = %for.cond.cleanup3
    150   call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull %0)
    151   ret i32 %add
    152 
    153 for.cond.cleanup3:                                ; preds = %for.body4
    154   %indvars.iv.next24 = add nuw nsw i64 %indvars.iv23, 1
    155   %exitcond25 = icmp eq i64 %indvars.iv.next24, 2
    156   br i1 %exitcond25, label %for.cond.cleanup, label %for.cond1.preheader
    157 
    158 for.body4:                                        ; preds = %for.body4, %for.cond1.preheader
    159   %indvars.iv = phi i64 [ 0, %for.cond1.preheader ], [ %indvars.iv.next, %for.body4 ]
    160   %sum.119 = phi i32 [ %sum.021, %for.cond1.preheader ], [ %add, %for.body4 ]
    161   %arrayidx7 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %foo, i64 0, i64 %indvars.iv23, i64 %indvars.iv
    162 ; CHECK-NOT: trap
    163   %1 = load i32, i32* %arrayidx7, align 4
    164   %add = add nsw i32 %1, %sum.119
    165   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
    166   %exitcond = icmp eq i64 %indvars.iv.next, 2
    167   br i1 %exitcond, label %for.cond.cleanup3, label %for.body4
    168 }
    169 
    170 ; CHECK-LABEL: @twoDimLarger1
    171 define dso_local i32 @twoDimLarger1(i32 %n) {
    172 entry:
    173   %foo = alloca [2 x [2 x i32]], align 16
    174   %0 = bitcast [2 x [2 x i32]]* %foo to i8*
    175   call void @llvm.lifetime.start.p0i8(i64 16, i8* nonnull %0)
    176   %arraydecay = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %foo, i64 0, i64 0, i64 0
    177   call void @fill(i32* nonnull %arraydecay, i32 %n)
    178   br label %for.cond1.preheader
    179 
    180 for.cond1.preheader:                              ; preds = %for.cond.cleanup3, %entry
    181   %indvars.iv23 = phi i64 [ 0, %entry ], [ %indvars.iv.next24, %for.cond.cleanup3 ]
    182   %sum.021 = phi i32 [ 0, %entry ], [ %add, %for.cond.cleanup3 ]
    183   br label %for.body4
    184 
    185 for.cond.cleanup:                                 ; preds = %for.cond.cleanup3
    186   call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull %0)
    187   ret i32 %add
    188 
    189 for.cond.cleanup3:                                ; preds = %for.body4
    190   %indvars.iv.next24 = add nuw nsw i64 %indvars.iv23, 1
    191   %exitcond25 = icmp eq i64 %indvars.iv.next24, 3
    192   br i1 %exitcond25, label %for.cond.cleanup, label %for.cond1.preheader
    193 
    194 for.body4:                                        ; preds = %for.body4, %for.cond1.preheader
    195   %indvars.iv = phi i64 [ 0, %for.cond1.preheader ], [ %indvars.iv.next, %for.body4 ]
    196   %sum.119 = phi i32 [ %sum.021, %for.cond1.preheader ], [ %add, %for.body4 ]
    197   %arrayidx7 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %foo, i64 0, i64 %indvars.iv23, i64 %indvars.iv
    198 ; CHECK: mul i64 {{.*}}, 8
    199 ; CHECK: mul i64 {{.*}}, 4
    200 ; CHECK: add i64
    201 ; CHECK: sub i64 16, %
    202 ; CHECK-NEXT: icmp ult i64 16, %
    203 ; CHECK-NEXT: icmp ult i64 {{.*}}, 4
    204 ; CHECK-NEXT: or i1
    205 ; CHECK: trap
    206   %1 = load i32, i32* %arrayidx7, align 4
    207   %add = add nsw i32 %1, %sum.119
    208   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
    209   %exitcond = icmp eq i64 %indvars.iv.next, 2
    210   br i1 %exitcond, label %for.cond.cleanup3, label %for.body4
    211 }
    212 
    213 ; CHECK-LABEL: @twoDimLarger2
    214 define dso_local i32 @twoDimLarger2(i32 %n) {
    215 entry:
    216   %foo = alloca [2 x [2 x i32]], align 16
    217   %0 = bitcast [2 x [2 x i32]]* %foo to i8*
    218   call void @llvm.lifetime.start.p0i8(i64 16, i8* nonnull %0)
    219   %arraydecay = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %foo, i64 0, i64 0, i64 0
    220   call void @fill(i32* nonnull %arraydecay, i32 %n)
    221   br label %for.cond1.preheader
    222 
    223 for.cond1.preheader:                              ; preds = %for.cond.cleanup3, %entry
    224   %indvars.iv23 = phi i64 [ 0, %entry ], [ %indvars.iv.next24, %for.cond.cleanup3 ]
    225   %sum.021 = phi i32 [ 0, %entry ], [ %add, %for.cond.cleanup3 ]
    226   br label %for.body4
    227 
    228 for.cond.cleanup:                                 ; preds = %for.cond.cleanup3
    229   call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull %0)
    230   ret i32 %add
    231 
    232 for.cond.cleanup3:                                ; preds = %for.body4
    233   %indvars.iv.next24 = add nuw nsw i64 %indvars.iv23, 1
    234   %exitcond25 = icmp eq i64 %indvars.iv.next24, 2
    235   br i1 %exitcond25, label %for.cond.cleanup, label %for.cond1.preheader
    236 
    237 for.body4:                                        ; preds = %for.body4, %for.cond1.preheader
    238   %indvars.iv = phi i64 [ 0, %for.cond1.preheader ], [ %indvars.iv.next, %for.body4 ]
    239   %sum.119 = phi i32 [ %sum.021, %for.cond1.preheader ], [ %add, %for.body4 ]
    240   %arrayidx7 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %foo, i64 0, i64 %indvars.iv23, i64 %indvars.iv
    241 ; CHECK: mul i64 {{.*}}, 8
    242 ; CHECK: mul i64 {{.*}}, 4
    243 ; CHECK: add i64
    244 ; CHECK: sub i64 16, %
    245 ; CHECK-NEXT: icmp ult i64 {{.*}}, 4
    246 ; CHECK-NEXT: or i1
    247 ; CHECK: trap
    248   %1 = load i32, i32* %arrayidx7, align 4
    249   %add = add nsw i32 %1, %sum.119
    250   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
    251   %exitcond = icmp eq i64 %indvars.iv.next, 3
    252   br i1 %exitcond, label %for.cond.cleanup3, label %for.body4
    253 }
    254 
    255 ; CHECK-LABEL: @twoDimUnknown
    256 define dso_local i32 @twoDimUnknown(i32 %n) {
    257 entry:
    258   %foo = alloca [2 x [2 x i32]], align 16
    259   %0 = bitcast [2 x [2 x i32]]* %foo to i8*
    260   call void @llvm.lifetime.start.p0i8(i64 16, i8* nonnull %0)
    261   %arraydecay = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %foo, i64 0, i64 0, i64 0
    262   call void @fill(i32* nonnull %arraydecay, i32 %n)
    263   %cmp24 = icmp eq i32 %n, 0
    264   br i1 %cmp24, label %for.cond.cleanup, label %for.cond1.preheader.lr.ph
    265 
    266 for.cond1.preheader.lr.ph:                        ; preds = %entry
    267   %wide.trip.count = zext i32 %n to i64
    268   %wide.trip.count.le = zext i32 %n to i64
    269   br label %for.body4.lr.ph
    270 
    271 for.body4.lr.ph:                                  ; preds = %for.cond1.preheader.lr.ph, %for.cond.cleanup3
    272   %indvars.iv28 = phi i64 [ 0, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next29, %for.cond.cleanup3 ]
    273   %sum.025 = phi i32 [ 0, %for.cond1.preheader.lr.ph ], [ %add, %for.cond.cleanup3 ]
    274   br label %for.body4
    275 
    276 for.cond.cleanup:                                 ; preds = %for.cond.cleanup3, %entry
    277   %sum.0.lcssa = phi i32 [ 0, %entry ], [ %add, %for.cond.cleanup3 ]
    278   call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull %0)
    279   ret i32 %sum.0.lcssa
    280 
    281 for.cond.cleanup3:                                ; preds = %for.body4
    282   %indvars.iv.next29 = add nuw nsw i64 %indvars.iv28, 1
    283   %exitcond31 = icmp eq i64 %indvars.iv.next29, %wide.trip.count.le
    284   br i1 %exitcond31, label %for.cond.cleanup, label %for.body4.lr.ph
    285 
    286 for.body4:                                        ; preds = %for.body4, %for.body4.lr.ph
    287   %indvars.iv = phi i64 [ 0, %for.body4.lr.ph ], [ %indvars.iv.next, %for.body4 ]
    288   %sum.122 = phi i32 [ %sum.025, %for.body4.lr.ph ], [ %add, %for.body4 ]
    289   %arrayidx7 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %foo, i64 0, i64 %indvars.iv28, i64 %indvars.iv
    290 ; CHECK: mul i64 {{.*}}, 8
    291 ; CHECK: mul i64 {{.*}}, 4
    292 ; CHECK: add i64
    293 ; CHECK: sub i64 16, %
    294 ; CHECK-NEXT: icmp ult i64 16, %
    295 ; CHECK-NEXT: icmp ult i64 {{.*}}, 4
    296 ; CHECK-NEXT: or i1
    297 ; CHECK: trap
    298   %1 = load i32, i32* %arrayidx7, align 4
    299   %add = add nsw i32 %1, %sum.122
    300   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
    301   %exitcond = icmp eq i64 %indvars.iv.next, %wide.trip.count
    302   br i1 %exitcond, label %for.cond.cleanup3, label %for.body4
    303 }
    304 
    305 ; CHECK-LABEL: @countDownGood
    306 define dso_local i32 @countDownGood(i32 %n) {
    307 entry:
    308   %foo = alloca [1000 x i32], align 16
    309   %0 = bitcast [1000 x i32]* %foo to i8*
    310   call void @llvm.lifetime.start.p0i8(i64 4000, i8* nonnull %0)
    311   %arraydecay = getelementptr inbounds [1000 x i32], [1000 x i32]* %foo, i64 0, i64 0
    312   call void @fill(i32* nonnull %arraydecay, i32 %n)
    313   br label %for.body
    314 
    315 for.cond.cleanup:                                 ; preds = %for.body
    316   call void @llvm.lifetime.end.p0i8(i64 4000, i8* nonnull %0)
    317   ret i32 %add
    318 
    319 for.body:                                         ; preds = %for.body, %entry
    320   %indvars.iv = phi i64 [ 999, %entry ], [ %indvars.iv.next, %for.body ]
    321   %sum.06 = phi i32 [ 0, %entry ], [ %add, %for.body ]
    322   %arrayidx = getelementptr inbounds [1000 x i32], [1000 x i32]* %foo, i64 0, i64 %indvars.iv
    323 ; CHECK-NOT: trap
    324   %1 = load i32, i32* %arrayidx, align 4
    325   %add = add nsw i32 %1, %sum.06
    326   %indvars.iv.next = add nsw i64 %indvars.iv, -1
    327   %cmp = icmp eq i64 %indvars.iv, 0
    328   br i1 %cmp, label %for.cond.cleanup, label %for.body
    329 }
    330 
    331 ; CHECK-LABEL: @countDownBad
    332 define dso_local i32 @countDownBad(i32 %n) {
    333 entry:
    334   %foo = alloca [1000 x i32], align 16
    335   %0 = bitcast [1000 x i32]* %foo to i8*
    336   call void @llvm.lifetime.start.p0i8(i64 4000, i8* nonnull %0)
    337   %arraydecay = getelementptr inbounds [1000 x i32], [1000 x i32]* %foo, i64 0, i64 0
    338   call void @fill(i32* nonnull %arraydecay, i32 %n)
    339   br label %for.body
    340 
    341 for.cond.cleanup:                                 ; preds = %for.body
    342   call void @llvm.lifetime.end.p0i8(i64 4000, i8* nonnull %0)
    343   ret i32 %add
    344 
    345 for.body:                                         ; preds = %entry, %for.body
    346   %indvars.iv = phi i64 [ 999, %entry ], [ %indvars.iv.next, %for.body ]
    347   %sum.06 = phi i32 [ 0, %entry ], [ %add, %for.body ]
    348   %arrayidx = getelementptr inbounds [1000 x i32], [1000 x i32]* %foo, i64 0, i64 %indvars.iv
    349 ; CHECK: mul i64 {{.*}}, 4
    350 ; CHECK: sub i64 4000, %
    351 ; CHECK-NEXT: icmp ult i64 4000, %
    352 ; CHECK: trap
    353   %1 = load i32, i32* %arrayidx, align 4
    354   %add = add nsw i32 %1, %sum.06
    355   %indvars.iv.next = add nsw i64 %indvars.iv, -1
    356   %cmp = icmp sgt i64 %indvars.iv, -1
    357   br i1 %cmp, label %for.body, label %for.cond.cleanup
    358 }
    359