1*261f219fSFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes 2*261f219fSFlorian Hahn; RUN: opt -indvars -S %s | FileCheck %s 3*261f219fSFlorian Hahn 4*261f219fSFlorian Hahn; Test cases inspired by PR48965. 5*261f219fSFlorian Hahn 6*261f219fSFlorian Hahn; %len is zero-extended before being used to compute %p.end, which guarantees 7*261f219fSFlorian Hahn; the offset is positive. %i.ult.ext can be simplified. 8*261f219fSFlorian Hahndefine i1 @can_simplify_ult_i32_ptr_len_zext(i32* %p.base, i32 %len) { 9*261f219fSFlorian Hahn; CHECK-LABEL: @can_simplify_ult_i32_ptr_len_zext( 10*261f219fSFlorian Hahn; CHECK-NEXT: entry: 11*261f219fSFlorian Hahn; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[LEN:%.*]] to i64 12*261f219fSFlorian Hahn; CHECK-NEXT: [[P_END:%.*]] = getelementptr inbounds i32, i32* [[P_BASE:%.*]], i64 [[EXT]] 13*261f219fSFlorian Hahn; CHECK-NEXT: [[LEN_NONZERO:%.*]] = icmp ne i32 [[LEN]], 0 14*261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NONZERO]], label [[HEADER_PREHEADER:%.*]], label [[TRAP:%.*]] 15*261f219fSFlorian Hahn; CHECK: header.preheader: 16*261f219fSFlorian Hahn; CHECK-NEXT: br label [[HEADER:%.*]] 17*261f219fSFlorian Hahn; CHECK: trap.loopexit: 18*261f219fSFlorian Hahn; CHECK-NEXT: br label [[TRAP]] 19*261f219fSFlorian Hahn; CHECK: trap: 20*261f219fSFlorian Hahn; CHECK-NEXT: ret i1 false 21*261f219fSFlorian Hahn; CHECK: header: 22*261f219fSFlorian Hahn; CHECK-NEXT: [[P:%.*]] = phi i32* [ [[P_INC:%.*]], [[LATCH:%.*]] ], [ [[P_BASE]], [[HEADER_PREHEADER]] ] 23*261f219fSFlorian Hahn; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_INC:%.*]], [[LATCH]] ], [ 0, [[HEADER_PREHEADER]] ] 24*261f219fSFlorian Hahn; CHECK-NEXT: [[I_INC]] = add nuw nsw i64 [[I]], 1 25*261f219fSFlorian Hahn; CHECK-NEXT: [[I_ULT_EXT:%.*]] = icmp ult i64 [[I]], [[EXT]] 26*261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[I_ULT_EXT]], label [[LATCH]], label [[TRAP_LOOPEXIT:%.*]] 27*261f219fSFlorian Hahn; CHECK: latch: 28*261f219fSFlorian Hahn; CHECK-NEXT: [[P_INC]] = getelementptr inbounds i32, i32* [[P]], i64 1 29*261f219fSFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp ne i32* [[P_INC]], [[P_END]] 30*261f219fSFlorian Hahn; CHECK-NEXT: store i32 0, i32* [[P]], align 4 31*261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[HEADER]], label [[EXIT:%.*]] 32*261f219fSFlorian Hahn; CHECK: exit: 33*261f219fSFlorian Hahn; CHECK-NEXT: ret i1 true 34*261f219fSFlorian Hahn; 35*261f219fSFlorian Hahnentry: 36*261f219fSFlorian Hahn %ext = zext i32 %len to i64 37*261f219fSFlorian Hahn %p.end = getelementptr inbounds i32, i32* %p.base, i64 %ext 38*261f219fSFlorian Hahn %len.nonzero = icmp ne i32 %len, 0 39*261f219fSFlorian Hahn br i1 %len.nonzero, label %header, label %trap 40*261f219fSFlorian Hahn 41*261f219fSFlorian Hahntrap: 42*261f219fSFlorian Hahn ret i1 false 43*261f219fSFlorian Hahn 44*261f219fSFlorian Hahnheader: 45*261f219fSFlorian Hahn %p = phi i32* [ %p.base, %entry ], [ %p.inc, %latch ] 46*261f219fSFlorian Hahn %i = phi i64 [ 0, %entry ], [ %i.inc, %latch] 47*261f219fSFlorian Hahn %i.inc = add nsw nuw i64 %i, 1 48*261f219fSFlorian Hahn %i.ult.ext = icmp ult i64 %i, %ext 49*261f219fSFlorian Hahn br i1 %i.ult.ext, label %latch, label %trap 50*261f219fSFlorian Hahn 51*261f219fSFlorian Hahnlatch: 52*261f219fSFlorian Hahn %p.inc = getelementptr inbounds i32, i32* %p, i64 1 53*261f219fSFlorian Hahn %c = icmp ne i32* %p.inc, %p.end 54*261f219fSFlorian Hahn store i32 0, i32* %p 55*261f219fSFlorian Hahn br i1 %c, label %header, label %exit 56*261f219fSFlorian Hahn 57*261f219fSFlorian Hahnexit: 58*261f219fSFlorian Hahn ret i1 true 59*261f219fSFlorian Hahn} 60*261f219fSFlorian Hahn 61*261f219fSFlorian Hahn; %len may be (signed) negative, %i.ult.ext cannot be simplified. 62*261f219fSFlorian Hahndefine i1 @cannot_simplify_ult_i32_ptr_len_ult(i32* %p.base, i64 %len) { 63*261f219fSFlorian Hahn; CHECK-LABEL: @cannot_simplify_ult_i32_ptr_len_ult( 64*261f219fSFlorian Hahn; CHECK-NEXT: entry: 65*261f219fSFlorian Hahn; CHECK-NEXT: [[P_END:%.*]] = getelementptr inbounds i32, i32* [[P_BASE:%.*]], i64 [[LEN:%.*]] 66*261f219fSFlorian Hahn; CHECK-NEXT: [[LEN_NONZERO:%.*]] = icmp ne i64 [[LEN]], 0 67*261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NONZERO]], label [[HEADER_PREHEADER:%.*]], label [[TRAP:%.*]] 68*261f219fSFlorian Hahn; CHECK: header.preheader: 69*261f219fSFlorian Hahn; CHECK-NEXT: br label [[HEADER:%.*]] 70*261f219fSFlorian Hahn; CHECK: trap.loopexit: 71*261f219fSFlorian Hahn; CHECK-NEXT: br label [[TRAP]] 72*261f219fSFlorian Hahn; CHECK: trap: 73*261f219fSFlorian Hahn; CHECK-NEXT: ret i1 false 74*261f219fSFlorian Hahn; CHECK: header: 75*261f219fSFlorian Hahn; CHECK-NEXT: [[P:%.*]] = phi i32* [ [[P_INC:%.*]], [[LATCH:%.*]] ], [ [[P_BASE]], [[HEADER_PREHEADER]] ] 76*261f219fSFlorian Hahn; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_INC:%.*]], [[LATCH]] ], [ 0, [[HEADER_PREHEADER]] ] 77*261f219fSFlorian Hahn; CHECK-NEXT: [[I_INC]] = add nuw nsw i64 [[I]], 1 78*261f219fSFlorian Hahn; CHECK-NEXT: [[I_ULT_EXT:%.*]] = icmp ult i64 [[I]], [[LEN]] 79*261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[I_ULT_EXT]], label [[LATCH]], label [[TRAP_LOOPEXIT:%.*]] 80*261f219fSFlorian Hahn; CHECK: latch: 81*261f219fSFlorian Hahn; CHECK-NEXT: [[P_INC]] = getelementptr inbounds i32, i32* [[P]], i64 1 82*261f219fSFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp ne i32* [[P_INC]], [[P_END]] 83*261f219fSFlorian Hahn; CHECK-NEXT: store i32 0, i32* [[P]], align 4 84*261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[HEADER]], label [[EXIT:%.*]] 85*261f219fSFlorian Hahn; CHECK: exit: 86*261f219fSFlorian Hahn; CHECK-NEXT: ret i1 true 87*261f219fSFlorian Hahn; 88*261f219fSFlorian Hahnentry: 89*261f219fSFlorian Hahn %p.end = getelementptr inbounds i32, i32* %p.base, i64 %len 90*261f219fSFlorian Hahn %len.nonzero = icmp ne i64 %len, 0 91*261f219fSFlorian Hahn br i1 %len.nonzero, label %header, label %trap 92*261f219fSFlorian Hahn 93*261f219fSFlorian Hahntrap: 94*261f219fSFlorian Hahn ret i1 false 95*261f219fSFlorian Hahn 96*261f219fSFlorian Hahnheader: 97*261f219fSFlorian Hahn %p = phi i32* [ %p.base, %entry ], [ %p.inc, %latch ] 98*261f219fSFlorian Hahn %i = phi i64 [ 0, %entry ], [ %i.inc, %latch] 99*261f219fSFlorian Hahn %i.inc = add nsw nuw i64 %i, 1 100*261f219fSFlorian Hahn %i.ult.ext = icmp ult i64 %i, %len 101*261f219fSFlorian Hahn br i1 %i.ult.ext, label %latch, label %trap 102*261f219fSFlorian Hahn 103*261f219fSFlorian Hahnlatch: 104*261f219fSFlorian Hahn %p.inc = getelementptr inbounds i32, i32* %p, i64 1 105*261f219fSFlorian Hahn %c = icmp ne i32* %p.inc, %p.end 106*261f219fSFlorian Hahn store i32 0, i32* %p 107*261f219fSFlorian Hahn br i1 %c, label %header, label %exit 108*261f219fSFlorian Hahn 109*261f219fSFlorian Hahnexit: 110*261f219fSFlorian Hahn ret i1 true 111*261f219fSFlorian Hahn} 112*261f219fSFlorian Hahn 113*261f219fSFlorian Hahn; Similar to can_simplify_ult_i32_ptr_len_zext, but %i has 1 as start value. %i.ult.ext cannot be simplified. 114*261f219fSFlorian Hahndefine i1 @cannot_simplify_ult_i32_ptr_len_zext(i32* %p.base, i32 %len) { 115*261f219fSFlorian Hahn; CHECK-LABEL: @cannot_simplify_ult_i32_ptr_len_zext( 116*261f219fSFlorian Hahn; CHECK-NEXT: entry: 117*261f219fSFlorian Hahn; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[LEN:%.*]] to i64 118*261f219fSFlorian Hahn; CHECK-NEXT: [[P_END:%.*]] = getelementptr inbounds i32, i32* [[P_BASE:%.*]], i64 [[EXT]] 119*261f219fSFlorian Hahn; CHECK-NEXT: [[LEN_NONZERO:%.*]] = icmp ne i32 [[LEN]], 0 120*261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NONZERO]], label [[HEADER_PREHEADER:%.*]], label [[TRAP:%.*]] 121*261f219fSFlorian Hahn; CHECK: header.preheader: 122*261f219fSFlorian Hahn; CHECK-NEXT: br label [[HEADER:%.*]] 123*261f219fSFlorian Hahn; CHECK: trap.loopexit: 124*261f219fSFlorian Hahn; CHECK-NEXT: br label [[TRAP]] 125*261f219fSFlorian Hahn; CHECK: trap: 126*261f219fSFlorian Hahn; CHECK-NEXT: ret i1 false 127*261f219fSFlorian Hahn; CHECK: header: 128*261f219fSFlorian Hahn; CHECK-NEXT: [[P:%.*]] = phi i32* [ [[P_INC:%.*]], [[LATCH:%.*]] ], [ [[P_BASE]], [[HEADER_PREHEADER]] ] 129*261f219fSFlorian Hahn; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_INC:%.*]], [[LATCH]] ], [ 1, [[HEADER_PREHEADER]] ] 130*261f219fSFlorian Hahn; CHECK-NEXT: [[I_INC]] = add nuw nsw i64 [[I]], 1 131*261f219fSFlorian Hahn; CHECK-NEXT: [[I_ULT_EXT:%.*]] = icmp ult i64 [[I]], [[EXT]] 132*261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[I_ULT_EXT]], label [[LATCH]], label [[TRAP_LOOPEXIT:%.*]] 133*261f219fSFlorian Hahn; CHECK: latch: 134*261f219fSFlorian Hahn; CHECK-NEXT: [[P_INC]] = getelementptr inbounds i32, i32* [[P]], i64 1 135*261f219fSFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp ne i32* [[P_INC]], [[P_END]] 136*261f219fSFlorian Hahn; CHECK-NEXT: store i32 0, i32* [[P]], align 4 137*261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[HEADER]], label [[EXIT:%.*]] 138*261f219fSFlorian Hahn; CHECK: exit: 139*261f219fSFlorian Hahn; CHECK-NEXT: ret i1 true 140*261f219fSFlorian Hahn; 141*261f219fSFlorian Hahnentry: 142*261f219fSFlorian Hahn %ext = zext i32 %len to i64 143*261f219fSFlorian Hahn %p.end = getelementptr inbounds i32, i32* %p.base, i64 %ext 144*261f219fSFlorian Hahn %len.nonzero = icmp ne i32 %len, 0 145*261f219fSFlorian Hahn br i1 %len.nonzero, label %header, label %trap 146*261f219fSFlorian Hahn 147*261f219fSFlorian Hahntrap: 148*261f219fSFlorian Hahn ret i1 false 149*261f219fSFlorian Hahn 150*261f219fSFlorian Hahnheader: 151*261f219fSFlorian Hahn %p = phi i32* [ %p.base, %entry ], [ %p.inc, %latch ] 152*261f219fSFlorian Hahn %i = phi i64 [ 1, %entry ], [ %i.inc, %latch] 153*261f219fSFlorian Hahn %i.inc = add nsw nuw i64 %i, 1 154*261f219fSFlorian Hahn %i.ult.ext = icmp ult i64 %i, %ext 155*261f219fSFlorian Hahn br i1 %i.ult.ext, label %latch, label %trap 156*261f219fSFlorian Hahn 157*261f219fSFlorian Hahnlatch: 158*261f219fSFlorian Hahn %p.inc = getelementptr inbounds i32, i32* %p, i64 1 159*261f219fSFlorian Hahn %c = icmp ne i32* %p.inc, %p.end 160*261f219fSFlorian Hahn store i32 0, i32* %p 161*261f219fSFlorian Hahn br i1 %c, label %header, label %exit 162*261f219fSFlorian Hahn 163*261f219fSFlorian Hahnexit: 164*261f219fSFlorian Hahn ret i1 true 165*261f219fSFlorian Hahn} 166*261f219fSFlorian Hahn 167*261f219fSFlorian Hahndefine i1 @can_simplify_ule_i32_ptr_len_zext(i32* %p.base, i32 %len) { 168*261f219fSFlorian Hahn; CHECK-LABEL: @can_simplify_ule_i32_ptr_len_zext( 169*261f219fSFlorian Hahn; CHECK-NEXT: entry: 170*261f219fSFlorian Hahn; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[LEN:%.*]] to i64 171*261f219fSFlorian Hahn; CHECK-NEXT: [[P_END:%.*]] = getelementptr inbounds i32, i32* [[P_BASE:%.*]], i64 [[EXT]] 172*261f219fSFlorian Hahn; CHECK-NEXT: [[LEN_NONZERO:%.*]] = icmp ne i32 [[LEN]], 0 173*261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NONZERO]], label [[HEADER_PREHEADER:%.*]], label [[TRAP:%.*]] 174*261f219fSFlorian Hahn; CHECK: header.preheader: 175*261f219fSFlorian Hahn; CHECK-NEXT: br label [[HEADER:%.*]] 176*261f219fSFlorian Hahn; CHECK: trap.loopexit: 177*261f219fSFlorian Hahn; CHECK-NEXT: br label [[TRAP]] 178*261f219fSFlorian Hahn; CHECK: trap: 179*261f219fSFlorian Hahn; CHECK-NEXT: ret i1 false 180*261f219fSFlorian Hahn; CHECK: header: 181*261f219fSFlorian Hahn; CHECK-NEXT: [[P:%.*]] = phi i32* [ [[P_INC:%.*]], [[LATCH:%.*]] ], [ [[P_BASE]], [[HEADER_PREHEADER]] ] 182*261f219fSFlorian Hahn; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_INC:%.*]], [[LATCH]] ], [ 1, [[HEADER_PREHEADER]] ] 183*261f219fSFlorian Hahn; CHECK-NEXT: [[I_INC]] = add nuw nsw i64 [[I]], 1 184*261f219fSFlorian Hahn; CHECK-NEXT: [[I_ULT_EXT:%.*]] = icmp ule i64 [[I]], [[EXT]] 185*261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[I_ULT_EXT]], label [[LATCH]], label [[TRAP_LOOPEXIT:%.*]] 186*261f219fSFlorian Hahn; CHECK: latch: 187*261f219fSFlorian Hahn; CHECK-NEXT: [[P_INC]] = getelementptr inbounds i32, i32* [[P]], i64 1 188*261f219fSFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp ne i32* [[P_INC]], [[P_END]] 189*261f219fSFlorian Hahn; CHECK-NEXT: store i32 0, i32* [[P]], align 4 190*261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[HEADER]], label [[EXIT:%.*]] 191*261f219fSFlorian Hahn; CHECK: exit: 192*261f219fSFlorian Hahn; CHECK-NEXT: ret i1 true 193*261f219fSFlorian Hahn; 194*261f219fSFlorian Hahnentry: 195*261f219fSFlorian Hahn %ext = zext i32 %len to i64 196*261f219fSFlorian Hahn %p.end = getelementptr inbounds i32, i32* %p.base, i64 %ext 197*261f219fSFlorian Hahn %len.nonzero = icmp ne i32 %len, 0 198*261f219fSFlorian Hahn br i1 %len.nonzero, label %header, label %trap 199*261f219fSFlorian Hahn 200*261f219fSFlorian Hahntrap: 201*261f219fSFlorian Hahn ret i1 false 202*261f219fSFlorian Hahn 203*261f219fSFlorian Hahnheader: 204*261f219fSFlorian Hahn %p = phi i32* [ %p.base, %entry ], [ %p.inc, %latch ] 205*261f219fSFlorian Hahn %i = phi i64 [ 1, %entry ], [ %i.inc, %latch] 206*261f219fSFlorian Hahn %i.inc = add nsw nuw i64 %i, 1 207*261f219fSFlorian Hahn %i.ult.ext = icmp ule i64 %i, %ext 208*261f219fSFlorian Hahn br i1 %i.ult.ext, label %latch, label %trap 209*261f219fSFlorian Hahn 210*261f219fSFlorian Hahnlatch: 211*261f219fSFlorian Hahn %p.inc = getelementptr inbounds i32, i32* %p, i64 1 212*261f219fSFlorian Hahn %c = icmp ne i32* %p.inc, %p.end 213*261f219fSFlorian Hahn store i32 0, i32* %p 214*261f219fSFlorian Hahn br i1 %c, label %header, label %exit 215*261f219fSFlorian Hahn 216*261f219fSFlorian Hahnexit: 217*261f219fSFlorian Hahn ret i1 true 218*261f219fSFlorian Hahn} 219*261f219fSFlorian Hahn 220*261f219fSFlorian Hahn; %len is zero-extended before being used to compute %p.end, which guarantees 221*261f219fSFlorian Hahn; the offset is positive. %i.uge.ext can be simplified. 222*261f219fSFlorian Hahndefine i1 @can_simplify_uge_i32_ptr_len_zext(i32* %p.base, i32 %len) { 223*261f219fSFlorian Hahn; CHECK-LABEL: @can_simplify_uge_i32_ptr_len_zext( 224*261f219fSFlorian Hahn; CHECK-NEXT: entry: 225*261f219fSFlorian Hahn; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[LEN:%.*]] to i64 226*261f219fSFlorian Hahn; CHECK-NEXT: [[P_END:%.*]] = getelementptr inbounds i32, i32* [[P_BASE:%.*]], i64 [[EXT]] 227*261f219fSFlorian Hahn; CHECK-NEXT: [[LEN_NONZERO:%.*]] = icmp ne i32 [[LEN]], 0 228*261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NONZERO]], label [[HEADER_PREHEADER:%.*]], label [[TRAP:%.*]] 229*261f219fSFlorian Hahn; CHECK: header.preheader: 230*261f219fSFlorian Hahn; CHECK-NEXT: br label [[HEADER:%.*]] 231*261f219fSFlorian Hahn; CHECK: trap.loopexit: 232*261f219fSFlorian Hahn; CHECK-NEXT: br label [[TRAP]] 233*261f219fSFlorian Hahn; CHECK: trap: 234*261f219fSFlorian Hahn; CHECK-NEXT: ret i1 false 235*261f219fSFlorian Hahn; CHECK: header: 236*261f219fSFlorian Hahn; CHECK-NEXT: [[P:%.*]] = phi i32* [ [[P_INC:%.*]], [[LATCH:%.*]] ], [ [[P_BASE]], [[HEADER_PREHEADER]] ] 237*261f219fSFlorian Hahn; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_INC:%.*]], [[LATCH]] ], [ 0, [[HEADER_PREHEADER]] ] 238*261f219fSFlorian Hahn; CHECK-NEXT: [[I_INC]] = add nuw nsw i64 [[I]], 1 239*261f219fSFlorian Hahn; CHECK-NEXT: [[I_UGE_EXT:%.*]] = icmp uge i64 [[I]], [[EXT]] 240*261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[I_UGE_EXT]], label [[TRAP_LOOPEXIT:%.*]], label [[LATCH]] 241*261f219fSFlorian Hahn; CHECK: latch: 242*261f219fSFlorian Hahn; CHECK-NEXT: [[P_INC]] = getelementptr inbounds i32, i32* [[P]], i64 1 243*261f219fSFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp ne i32* [[P_INC]], [[P_END]] 244*261f219fSFlorian Hahn; CHECK-NEXT: store i32 0, i32* [[P]], align 4 245*261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[HEADER]], label [[EXIT:%.*]] 246*261f219fSFlorian Hahn; CHECK: exit: 247*261f219fSFlorian Hahn; CHECK-NEXT: ret i1 true 248*261f219fSFlorian Hahn; 249*261f219fSFlorian Hahnentry: 250*261f219fSFlorian Hahn %ext = zext i32 %len to i64 251*261f219fSFlorian Hahn %p.end = getelementptr inbounds i32, i32* %p.base, i64 %ext 252*261f219fSFlorian Hahn %len.nonzero = icmp ne i32 %len, 0 253*261f219fSFlorian Hahn br i1 %len.nonzero, label %header, label %trap 254*261f219fSFlorian Hahn 255*261f219fSFlorian Hahntrap: 256*261f219fSFlorian Hahn ret i1 false 257*261f219fSFlorian Hahn 258*261f219fSFlorian Hahnheader: 259*261f219fSFlorian Hahn %p = phi i32* [ %p.base, %entry ], [ %p.inc, %latch ] 260*261f219fSFlorian Hahn %i = phi i64 [ 0, %entry ], [ %i.inc, %latch] 261*261f219fSFlorian Hahn %i.inc = add nsw nuw i64 %i, 1 262*261f219fSFlorian Hahn %i.uge.ext = icmp uge i64 %i, %ext 263*261f219fSFlorian Hahn br i1 %i.uge.ext, label %trap, label %latch 264*261f219fSFlorian Hahn 265*261f219fSFlorian Hahnlatch: 266*261f219fSFlorian Hahn %p.inc = getelementptr inbounds i32, i32* %p, i64 1 267*261f219fSFlorian Hahn %c = icmp ne i32* %p.inc, %p.end 268*261f219fSFlorian Hahn store i32 0, i32* %p 269*261f219fSFlorian Hahn br i1 %c, label %header, label %exit 270*261f219fSFlorian Hahn 271*261f219fSFlorian Hahnexit: 272*261f219fSFlorian Hahn ret i1 true 273*261f219fSFlorian Hahn} 274*261f219fSFlorian Hahn 275*261f219fSFlorian Hahndefine i1 @cannot_simplify_uge_i32_ptr_len(i32* %p.base, i64 %len) { 276*261f219fSFlorian Hahn; CHECK-LABEL: @cannot_simplify_uge_i32_ptr_len( 277*261f219fSFlorian Hahn; CHECK-NEXT: entry: 278*261f219fSFlorian Hahn; CHECK-NEXT: [[P_END:%.*]] = getelementptr inbounds i32, i32* [[P_BASE:%.*]], i64 [[LEN:%.*]] 279*261f219fSFlorian Hahn; CHECK-NEXT: [[LEN_NONZERO:%.*]] = icmp ne i64 [[LEN]], 0 280*261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NONZERO]], label [[HEADER_PREHEADER:%.*]], label [[TRAP:%.*]] 281*261f219fSFlorian Hahn; CHECK: header.preheader: 282*261f219fSFlorian Hahn; CHECK-NEXT: br label [[HEADER:%.*]] 283*261f219fSFlorian Hahn; CHECK: trap.loopexit: 284*261f219fSFlorian Hahn; CHECK-NEXT: br label [[TRAP]] 285*261f219fSFlorian Hahn; CHECK: trap: 286*261f219fSFlorian Hahn; CHECK-NEXT: ret i1 false 287*261f219fSFlorian Hahn; CHECK: header: 288*261f219fSFlorian Hahn; CHECK-NEXT: [[P:%.*]] = phi i32* [ [[P_INC:%.*]], [[LATCH:%.*]] ], [ [[P_BASE]], [[HEADER_PREHEADER]] ] 289*261f219fSFlorian Hahn; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_INC:%.*]], [[LATCH]] ], [ 0, [[HEADER_PREHEADER]] ] 290*261f219fSFlorian Hahn; CHECK-NEXT: [[I_INC]] = add nuw nsw i64 [[I]], 1 291*261f219fSFlorian Hahn; CHECK-NEXT: [[I_UGE_EXT:%.*]] = icmp uge i64 [[I]], [[LEN]] 292*261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[I_UGE_EXT]], label [[TRAP_LOOPEXIT:%.*]], label [[LATCH]] 293*261f219fSFlorian Hahn; CHECK: latch: 294*261f219fSFlorian Hahn; CHECK-NEXT: [[P_INC]] = getelementptr inbounds i32, i32* [[P]], i64 1 295*261f219fSFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp ne i32* [[P_INC]], [[P_END]] 296*261f219fSFlorian Hahn; CHECK-NEXT: store i32 0, i32* [[P]], align 4 297*261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[HEADER]], label [[EXIT:%.*]] 298*261f219fSFlorian Hahn; CHECK: exit: 299*261f219fSFlorian Hahn; CHECK-NEXT: ret i1 true 300*261f219fSFlorian Hahn; 301*261f219fSFlorian Hahnentry: 302*261f219fSFlorian Hahn %p.end = getelementptr inbounds i32, i32* %p.base, i64 %len 303*261f219fSFlorian Hahn %len.nonzero = icmp ne i64 %len, 0 304*261f219fSFlorian Hahn br i1 %len.nonzero, label %header, label %trap 305*261f219fSFlorian Hahn 306*261f219fSFlorian Hahntrap: 307*261f219fSFlorian Hahn ret i1 false 308*261f219fSFlorian Hahn 309*261f219fSFlorian Hahnheader: 310*261f219fSFlorian Hahn %p = phi i32* [ %p.base, %entry ], [ %p.inc, %latch ] 311*261f219fSFlorian Hahn %i = phi i64 [ 0, %entry ], [ %i.inc, %latch] 312*261f219fSFlorian Hahn %i.inc = add nsw nuw i64 %i, 1 313*261f219fSFlorian Hahn %i.uge.ext = icmp uge i64 %i, %len 314*261f219fSFlorian Hahn br i1 %i.uge.ext, label %trap, label %latch 315*261f219fSFlorian Hahn 316*261f219fSFlorian Hahnlatch: 317*261f219fSFlorian Hahn %p.inc = getelementptr inbounds i32, i32* %p, i64 1 318*261f219fSFlorian Hahn %c = icmp ne i32* %p.inc, %p.end 319*261f219fSFlorian Hahn store i32 0, i32* %p 320*261f219fSFlorian Hahn br i1 %c, label %header, label %exit 321*261f219fSFlorian Hahn 322*261f219fSFlorian Hahnexit: 323*261f219fSFlorian Hahn ret i1 true 324*261f219fSFlorian Hahn} 325*261f219fSFlorian Hahn 326*261f219fSFlorian Hahndefine i1 @cannot_simplify_uge_i32_ptr_len_zext_step_2(i32* %p.base, i32 %len) { 327*261f219fSFlorian Hahn; CHECK-LABEL: @cannot_simplify_uge_i32_ptr_len_zext_step_2( 328*261f219fSFlorian Hahn; CHECK-NEXT: entry: 329*261f219fSFlorian Hahn; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[LEN:%.*]] to i64 330*261f219fSFlorian Hahn; CHECK-NEXT: [[P_END:%.*]] = getelementptr inbounds i32, i32* [[P_BASE:%.*]], i64 [[EXT]] 331*261f219fSFlorian Hahn; CHECK-NEXT: [[LEN_NONZERO:%.*]] = icmp ne i32 [[LEN]], 0 332*261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NONZERO]], label [[HEADER_PREHEADER:%.*]], label [[TRAP:%.*]] 333*261f219fSFlorian Hahn; CHECK: header.preheader: 334*261f219fSFlorian Hahn; CHECK-NEXT: br label [[HEADER:%.*]] 335*261f219fSFlorian Hahn; CHECK: trap.loopexit: 336*261f219fSFlorian Hahn; CHECK-NEXT: br label [[TRAP]] 337*261f219fSFlorian Hahn; CHECK: trap: 338*261f219fSFlorian Hahn; CHECK-NEXT: ret i1 false 339*261f219fSFlorian Hahn; CHECK: header: 340*261f219fSFlorian Hahn; CHECK-NEXT: [[P:%.*]] = phi i32* [ [[P_INC:%.*]], [[LATCH:%.*]] ], [ [[P_BASE]], [[HEADER_PREHEADER]] ] 341*261f219fSFlorian Hahn; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_INC:%.*]], [[LATCH]] ], [ 0, [[HEADER_PREHEADER]] ] 342*261f219fSFlorian Hahn; CHECK-NEXT: [[I_INC]] = add nuw nsw i64 [[I]], 2 343*261f219fSFlorian Hahn; CHECK-NEXT: [[I_UGE_EXT:%.*]] = icmp uge i64 [[I]], [[EXT]] 344*261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[I_UGE_EXT]], label [[TRAP_LOOPEXIT:%.*]], label [[LATCH]] 345*261f219fSFlorian Hahn; CHECK: latch: 346*261f219fSFlorian Hahn; CHECK-NEXT: [[P_INC]] = getelementptr inbounds i32, i32* [[P]], i64 1 347*261f219fSFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp ne i32* [[P_INC]], [[P_END]] 348*261f219fSFlorian Hahn; CHECK-NEXT: store i32 0, i32* [[P]], align 4 349*261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[HEADER]], label [[EXIT:%.*]] 350*261f219fSFlorian Hahn; CHECK: exit: 351*261f219fSFlorian Hahn; CHECK-NEXT: ret i1 true 352*261f219fSFlorian Hahn; 353*261f219fSFlorian Hahnentry: 354*261f219fSFlorian Hahn %ext = zext i32 %len to i64 355*261f219fSFlorian Hahn %p.end = getelementptr inbounds i32, i32* %p.base, i64 %ext 356*261f219fSFlorian Hahn %len.nonzero = icmp ne i32 %len, 0 357*261f219fSFlorian Hahn br i1 %len.nonzero, label %header, label %trap 358*261f219fSFlorian Hahn 359*261f219fSFlorian Hahntrap: 360*261f219fSFlorian Hahn ret i1 false 361*261f219fSFlorian Hahn 362*261f219fSFlorian Hahnheader: 363*261f219fSFlorian Hahn %p = phi i32* [ %p.base, %entry ], [ %p.inc, %latch ] 364*261f219fSFlorian Hahn %i = phi i64 [ 0, %entry ], [ %i.inc, %latch] 365*261f219fSFlorian Hahn %i.inc = add nsw nuw i64 %i, 2 366*261f219fSFlorian Hahn %i.uge.ext = icmp uge i64 %i, %ext 367*261f219fSFlorian Hahn br i1 %i.uge.ext, label %trap, label %latch 368*261f219fSFlorian Hahn 369*261f219fSFlorian Hahnlatch: 370*261f219fSFlorian Hahn %p.inc = getelementptr inbounds i32, i32* %p, i64 1 371*261f219fSFlorian Hahn %c = icmp ne i32* %p.inc, %p.end 372*261f219fSFlorian Hahn store i32 0, i32* %p 373*261f219fSFlorian Hahn br i1 %c, label %header, label %exit 374*261f219fSFlorian Hahn 375*261f219fSFlorian Hahnexit: 376*261f219fSFlorian Hahn ret i1 true 377*261f219fSFlorian Hahn} 378