1261f219fSFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes 2f15ed06aSBjorn Pettersson; RUN: opt -passes=indvars -S %s | FileCheck %s 3261f219fSFlorian Hahn 4261f219fSFlorian Hahn; Test cases inspired by PR48965. 5261f219fSFlorian Hahn 6261f219fSFlorian Hahn; %len is zero-extended before being used to compute %p.end, which guarantees 7261f219fSFlorian Hahn; the offset is positive. %i.ult.ext can be simplified. 8*864bb84aSNikita Popovdefine i1 @can_simplify_ult_i32_ptr_len_zext(ptr %p.base, i32 %len) { 9261f219fSFlorian Hahn; CHECK-LABEL: @can_simplify_ult_i32_ptr_len_zext( 10261f219fSFlorian Hahn; CHECK-NEXT: entry: 11261f219fSFlorian Hahn; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[LEN:%.*]] to i64 12*864bb84aSNikita Popov; CHECK-NEXT: [[P_END:%.*]] = getelementptr inbounds i32, ptr [[P_BASE:%.*]], i64 [[EXT]] 13261f219fSFlorian Hahn; CHECK-NEXT: [[LEN_NONZERO:%.*]] = icmp ne i32 [[LEN]], 0 14261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NONZERO]], label [[HEADER_PREHEADER:%.*]], label [[TRAP:%.*]] 15261f219fSFlorian Hahn; CHECK: header.preheader: 16261f219fSFlorian Hahn; CHECK-NEXT: br label [[HEADER:%.*]] 17261f219fSFlorian Hahn; CHECK: trap.loopexit: 18261f219fSFlorian Hahn; CHECK-NEXT: br label [[TRAP]] 19261f219fSFlorian Hahn; CHECK: trap: 20261f219fSFlorian Hahn; CHECK-NEXT: ret i1 false 21261f219fSFlorian Hahn; CHECK: header: 22*864bb84aSNikita Popov; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[P_INC:%.*]], [[LATCH:%.*]] ], [ [[P_BASE]], [[HEADER_PREHEADER]] ] 23261f219fSFlorian Hahn; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_INC:%.*]], [[LATCH]] ], [ 0, [[HEADER_PREHEADER]] ] 24261f219fSFlorian Hahn; CHECK-NEXT: [[I_INC]] = add nuw nsw i64 [[I]], 1 25261f219fSFlorian Hahn; CHECK-NEXT: [[I_ULT_EXT:%.*]] = icmp ult i64 [[I]], [[EXT]] 26261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[I_ULT_EXT]], label [[LATCH]], label [[TRAP_LOOPEXIT:%.*]] 27261f219fSFlorian Hahn; CHECK: latch: 28*864bb84aSNikita Popov; CHECK-NEXT: [[P_INC]] = getelementptr inbounds i32, ptr [[P]], i64 1 29*864bb84aSNikita Popov; CHECK-NEXT: [[C:%.*]] = icmp ne ptr [[P_INC]], [[P_END]] 30*864bb84aSNikita Popov; CHECK-NEXT: store i32 0, ptr [[P]], align 4 31261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[HEADER]], label [[EXIT:%.*]] 32261f219fSFlorian Hahn; CHECK: exit: 33261f219fSFlorian Hahn; CHECK-NEXT: ret i1 true 34261f219fSFlorian Hahn; 35261f219fSFlorian Hahnentry: 36261f219fSFlorian Hahn %ext = zext i32 %len to i64 37*864bb84aSNikita Popov %p.end = getelementptr inbounds i32, ptr %p.base, i64 %ext 38261f219fSFlorian Hahn %len.nonzero = icmp ne i32 %len, 0 39261f219fSFlorian Hahn br i1 %len.nonzero, label %header, label %trap 40261f219fSFlorian Hahn 41261f219fSFlorian Hahntrap: 42261f219fSFlorian Hahn ret i1 false 43261f219fSFlorian Hahn 44261f219fSFlorian Hahnheader: 45*864bb84aSNikita Popov %p = phi ptr [ %p.base, %entry ], [ %p.inc, %latch ] 46261f219fSFlorian Hahn %i = phi i64 [ 0, %entry ], [ %i.inc, %latch] 47261f219fSFlorian Hahn %i.inc = add nsw nuw i64 %i, 1 48261f219fSFlorian Hahn %i.ult.ext = icmp ult i64 %i, %ext 49261f219fSFlorian Hahn br i1 %i.ult.ext, label %latch, label %trap 50261f219fSFlorian Hahn 51261f219fSFlorian Hahnlatch: 52*864bb84aSNikita Popov %p.inc = getelementptr inbounds i32, ptr %p, i64 1 53*864bb84aSNikita Popov %c = icmp ne ptr %p.inc, %p.end 54*864bb84aSNikita Popov store i32 0, ptr %p 55261f219fSFlorian Hahn br i1 %c, label %header, label %exit 56261f219fSFlorian Hahn 57261f219fSFlorian Hahnexit: 58261f219fSFlorian Hahn ret i1 true 59261f219fSFlorian Hahn} 60261f219fSFlorian Hahn 61261f219fSFlorian Hahn; %len may be (signed) negative, %i.ult.ext cannot be simplified. 62*864bb84aSNikita Popovdefine i1 @cannot_simplify_ult_i32_ptr_len_ult(ptr %p.base, i64 %len) { 63261f219fSFlorian Hahn; CHECK-LABEL: @cannot_simplify_ult_i32_ptr_len_ult( 64261f219fSFlorian Hahn; CHECK-NEXT: entry: 65*864bb84aSNikita Popov; CHECK-NEXT: [[P_END:%.*]] = getelementptr inbounds i32, ptr [[P_BASE:%.*]], i64 [[LEN:%.*]] 66261f219fSFlorian Hahn; CHECK-NEXT: [[LEN_NONZERO:%.*]] = icmp ne i64 [[LEN]], 0 67261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NONZERO]], label [[HEADER_PREHEADER:%.*]], label [[TRAP:%.*]] 68261f219fSFlorian Hahn; CHECK: header.preheader: 69261f219fSFlorian Hahn; CHECK-NEXT: br label [[HEADER:%.*]] 70261f219fSFlorian Hahn; CHECK: trap.loopexit: 71261f219fSFlorian Hahn; CHECK-NEXT: br label [[TRAP]] 72261f219fSFlorian Hahn; CHECK: trap: 73261f219fSFlorian Hahn; CHECK-NEXT: ret i1 false 74261f219fSFlorian Hahn; CHECK: header: 75*864bb84aSNikita Popov; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[P_INC:%.*]], [[LATCH:%.*]] ], [ [[P_BASE]], [[HEADER_PREHEADER]] ] 76261f219fSFlorian Hahn; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_INC:%.*]], [[LATCH]] ], [ 0, [[HEADER_PREHEADER]] ] 77261f219fSFlorian Hahn; CHECK-NEXT: [[I_INC]] = add nuw nsw i64 [[I]], 1 78261f219fSFlorian Hahn; CHECK-NEXT: [[I_ULT_EXT:%.*]] = icmp ult i64 [[I]], [[LEN]] 79261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[I_ULT_EXT]], label [[LATCH]], label [[TRAP_LOOPEXIT:%.*]] 80261f219fSFlorian Hahn; CHECK: latch: 81*864bb84aSNikita Popov; CHECK-NEXT: [[P_INC]] = getelementptr inbounds i32, ptr [[P]], i64 1 82*864bb84aSNikita Popov; CHECK-NEXT: [[C:%.*]] = icmp ne ptr [[P_INC]], [[P_END]] 83*864bb84aSNikita Popov; CHECK-NEXT: store i32 0, ptr [[P]], align 4 84261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[HEADER]], label [[EXIT:%.*]] 85261f219fSFlorian Hahn; CHECK: exit: 86261f219fSFlorian Hahn; CHECK-NEXT: ret i1 true 87261f219fSFlorian Hahn; 88261f219fSFlorian Hahnentry: 89*864bb84aSNikita Popov %p.end = getelementptr inbounds i32, ptr %p.base, i64 %len 90261f219fSFlorian Hahn %len.nonzero = icmp ne i64 %len, 0 91261f219fSFlorian Hahn br i1 %len.nonzero, label %header, label %trap 92261f219fSFlorian Hahn 93261f219fSFlorian Hahntrap: 94261f219fSFlorian Hahn ret i1 false 95261f219fSFlorian Hahn 96261f219fSFlorian Hahnheader: 97*864bb84aSNikita Popov %p = phi ptr [ %p.base, %entry ], [ %p.inc, %latch ] 98261f219fSFlorian Hahn %i = phi i64 [ 0, %entry ], [ %i.inc, %latch] 99261f219fSFlorian Hahn %i.inc = add nsw nuw i64 %i, 1 100261f219fSFlorian Hahn %i.ult.ext = icmp ult i64 %i, %len 101261f219fSFlorian Hahn br i1 %i.ult.ext, label %latch, label %trap 102261f219fSFlorian Hahn 103261f219fSFlorian Hahnlatch: 104*864bb84aSNikita Popov %p.inc = getelementptr inbounds i32, ptr %p, i64 1 105*864bb84aSNikita Popov %c = icmp ne ptr %p.inc, %p.end 106*864bb84aSNikita Popov store i32 0, ptr %p 107261f219fSFlorian Hahn br i1 %c, label %header, label %exit 108261f219fSFlorian Hahn 109261f219fSFlorian Hahnexit: 110261f219fSFlorian Hahn ret i1 true 111261f219fSFlorian Hahn} 112261f219fSFlorian Hahn 113261f219fSFlorian Hahn; Similar to can_simplify_ult_i32_ptr_len_zext, but %i has 1 as start value. %i.ult.ext cannot be simplified. 114*864bb84aSNikita Popovdefine i1 @cannot_simplify_ult_i32_ptr_len_zext(ptr %p.base, i32 %len) { 115261f219fSFlorian Hahn; CHECK-LABEL: @cannot_simplify_ult_i32_ptr_len_zext( 116261f219fSFlorian Hahn; CHECK-NEXT: entry: 117261f219fSFlorian Hahn; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[LEN:%.*]] to i64 118*864bb84aSNikita Popov; CHECK-NEXT: [[P_END:%.*]] = getelementptr inbounds i32, ptr [[P_BASE:%.*]], i64 [[EXT]] 119261f219fSFlorian Hahn; CHECK-NEXT: [[LEN_NONZERO:%.*]] = icmp ne i32 [[LEN]], 0 120261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NONZERO]], label [[HEADER_PREHEADER:%.*]], label [[TRAP:%.*]] 121261f219fSFlorian Hahn; CHECK: header.preheader: 122261f219fSFlorian Hahn; CHECK-NEXT: br label [[HEADER:%.*]] 123261f219fSFlorian Hahn; CHECK: trap.loopexit: 124261f219fSFlorian Hahn; CHECK-NEXT: br label [[TRAP]] 125261f219fSFlorian Hahn; CHECK: trap: 126261f219fSFlorian Hahn; CHECK-NEXT: ret i1 false 127261f219fSFlorian Hahn; CHECK: header: 128*864bb84aSNikita Popov; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[P_INC:%.*]], [[LATCH:%.*]] ], [ [[P_BASE]], [[HEADER_PREHEADER]] ] 129261f219fSFlorian Hahn; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_INC:%.*]], [[LATCH]] ], [ 1, [[HEADER_PREHEADER]] ] 130261f219fSFlorian Hahn; CHECK-NEXT: [[I_INC]] = add nuw nsw i64 [[I]], 1 131261f219fSFlorian Hahn; CHECK-NEXT: [[I_ULT_EXT:%.*]] = icmp ult i64 [[I]], [[EXT]] 132261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[I_ULT_EXT]], label [[LATCH]], label [[TRAP_LOOPEXIT:%.*]] 133261f219fSFlorian Hahn; CHECK: latch: 134*864bb84aSNikita Popov; CHECK-NEXT: [[P_INC]] = getelementptr inbounds i32, ptr [[P]], i64 1 135*864bb84aSNikita Popov; CHECK-NEXT: [[C:%.*]] = icmp ne ptr [[P_INC]], [[P_END]] 136*864bb84aSNikita Popov; CHECK-NEXT: store i32 0, ptr [[P]], align 4 137261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[HEADER]], label [[EXIT:%.*]] 138261f219fSFlorian Hahn; CHECK: exit: 139261f219fSFlorian Hahn; CHECK-NEXT: ret i1 true 140261f219fSFlorian Hahn; 141261f219fSFlorian Hahnentry: 142261f219fSFlorian Hahn %ext = zext i32 %len to i64 143*864bb84aSNikita Popov %p.end = getelementptr inbounds i32, ptr %p.base, i64 %ext 144261f219fSFlorian Hahn %len.nonzero = icmp ne i32 %len, 0 145261f219fSFlorian Hahn br i1 %len.nonzero, label %header, label %trap 146261f219fSFlorian Hahn 147261f219fSFlorian Hahntrap: 148261f219fSFlorian Hahn ret i1 false 149261f219fSFlorian Hahn 150261f219fSFlorian Hahnheader: 151*864bb84aSNikita Popov %p = phi ptr [ %p.base, %entry ], [ %p.inc, %latch ] 152261f219fSFlorian Hahn %i = phi i64 [ 1, %entry ], [ %i.inc, %latch] 153261f219fSFlorian Hahn %i.inc = add nsw nuw i64 %i, 1 154261f219fSFlorian Hahn %i.ult.ext = icmp ult i64 %i, %ext 155261f219fSFlorian Hahn br i1 %i.ult.ext, label %latch, label %trap 156261f219fSFlorian Hahn 157261f219fSFlorian Hahnlatch: 158*864bb84aSNikita Popov %p.inc = getelementptr inbounds i32, ptr %p, i64 1 159*864bb84aSNikita Popov %c = icmp ne ptr %p.inc, %p.end 160*864bb84aSNikita Popov store i32 0, ptr %p 161261f219fSFlorian Hahn br i1 %c, label %header, label %exit 162261f219fSFlorian Hahn 163261f219fSFlorian Hahnexit: 164261f219fSFlorian Hahn ret i1 true 165261f219fSFlorian Hahn} 166261f219fSFlorian Hahn 167*864bb84aSNikita Popovdefine i1 @can_simplify_ule_i32_ptr_len_zext(ptr %p.base, i32 %len) { 168261f219fSFlorian Hahn; CHECK-LABEL: @can_simplify_ule_i32_ptr_len_zext( 169261f219fSFlorian Hahn; CHECK-NEXT: entry: 170261f219fSFlorian Hahn; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[LEN:%.*]] to i64 171*864bb84aSNikita Popov; CHECK-NEXT: [[P_END:%.*]] = getelementptr inbounds i32, ptr [[P_BASE:%.*]], i64 [[EXT]] 172261f219fSFlorian Hahn; CHECK-NEXT: [[LEN_NONZERO:%.*]] = icmp ne i32 [[LEN]], 0 173261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NONZERO]], label [[HEADER_PREHEADER:%.*]], label [[TRAP:%.*]] 174261f219fSFlorian Hahn; CHECK: header.preheader: 175261f219fSFlorian Hahn; CHECK-NEXT: br label [[HEADER:%.*]] 176261f219fSFlorian Hahn; CHECK: trap.loopexit: 177261f219fSFlorian Hahn; CHECK-NEXT: br label [[TRAP]] 178261f219fSFlorian Hahn; CHECK: trap: 179261f219fSFlorian Hahn; CHECK-NEXT: ret i1 false 180261f219fSFlorian Hahn; CHECK: header: 181*864bb84aSNikita Popov; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[P_INC:%.*]], [[LATCH:%.*]] ], [ [[P_BASE]], [[HEADER_PREHEADER]] ] 182261f219fSFlorian Hahn; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_INC:%.*]], [[LATCH]] ], [ 1, [[HEADER_PREHEADER]] ] 183261f219fSFlorian Hahn; CHECK-NEXT: [[I_INC]] = add nuw nsw i64 [[I]], 1 184261f219fSFlorian Hahn; CHECK-NEXT: [[I_ULT_EXT:%.*]] = icmp ule i64 [[I]], [[EXT]] 185261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[I_ULT_EXT]], label [[LATCH]], label [[TRAP_LOOPEXIT:%.*]] 186261f219fSFlorian Hahn; CHECK: latch: 187*864bb84aSNikita Popov; CHECK-NEXT: [[P_INC]] = getelementptr inbounds i32, ptr [[P]], i64 1 188*864bb84aSNikita Popov; CHECK-NEXT: [[C:%.*]] = icmp ne ptr [[P_INC]], [[P_END]] 189*864bb84aSNikita Popov; CHECK-NEXT: store i32 0, ptr [[P]], align 4 190261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[HEADER]], label [[EXIT:%.*]] 191261f219fSFlorian Hahn; CHECK: exit: 192261f219fSFlorian Hahn; CHECK-NEXT: ret i1 true 193261f219fSFlorian Hahn; 194261f219fSFlorian Hahnentry: 195261f219fSFlorian Hahn %ext = zext i32 %len to i64 196*864bb84aSNikita Popov %p.end = getelementptr inbounds i32, ptr %p.base, i64 %ext 197261f219fSFlorian Hahn %len.nonzero = icmp ne i32 %len, 0 198261f219fSFlorian Hahn br i1 %len.nonzero, label %header, label %trap 199261f219fSFlorian Hahn 200261f219fSFlorian Hahntrap: 201261f219fSFlorian Hahn ret i1 false 202261f219fSFlorian Hahn 203261f219fSFlorian Hahnheader: 204*864bb84aSNikita Popov %p = phi ptr [ %p.base, %entry ], [ %p.inc, %latch ] 205261f219fSFlorian Hahn %i = phi i64 [ 1, %entry ], [ %i.inc, %latch] 206261f219fSFlorian Hahn %i.inc = add nsw nuw i64 %i, 1 207261f219fSFlorian Hahn %i.ult.ext = icmp ule i64 %i, %ext 208261f219fSFlorian Hahn br i1 %i.ult.ext, label %latch, label %trap 209261f219fSFlorian Hahn 210261f219fSFlorian Hahnlatch: 211*864bb84aSNikita Popov %p.inc = getelementptr inbounds i32, ptr %p, i64 1 212*864bb84aSNikita Popov %c = icmp ne ptr %p.inc, %p.end 213*864bb84aSNikita Popov store i32 0, ptr %p 214261f219fSFlorian Hahn br i1 %c, label %header, label %exit 215261f219fSFlorian Hahn 216261f219fSFlorian Hahnexit: 217261f219fSFlorian Hahn ret i1 true 218261f219fSFlorian Hahn} 219261f219fSFlorian Hahn 220261f219fSFlorian Hahn; %len is zero-extended before being used to compute %p.end, which guarantees 221261f219fSFlorian Hahn; the offset is positive. %i.uge.ext can be simplified. 222*864bb84aSNikita Popovdefine i1 @can_simplify_uge_i32_ptr_len_zext(ptr %p.base, i32 %len) { 223261f219fSFlorian Hahn; CHECK-LABEL: @can_simplify_uge_i32_ptr_len_zext( 224261f219fSFlorian Hahn; CHECK-NEXT: entry: 225261f219fSFlorian Hahn; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[LEN:%.*]] to i64 226*864bb84aSNikita Popov; CHECK-NEXT: [[P_END:%.*]] = getelementptr inbounds i32, ptr [[P_BASE:%.*]], i64 [[EXT]] 227261f219fSFlorian Hahn; CHECK-NEXT: [[LEN_NONZERO:%.*]] = icmp ne i32 [[LEN]], 0 228261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NONZERO]], label [[HEADER_PREHEADER:%.*]], label [[TRAP:%.*]] 229261f219fSFlorian Hahn; CHECK: header.preheader: 230261f219fSFlorian Hahn; CHECK-NEXT: br label [[HEADER:%.*]] 231261f219fSFlorian Hahn; CHECK: trap.loopexit: 232261f219fSFlorian Hahn; CHECK-NEXT: br label [[TRAP]] 233261f219fSFlorian Hahn; CHECK: trap: 234261f219fSFlorian Hahn; CHECK-NEXT: ret i1 false 235261f219fSFlorian Hahn; CHECK: header: 236*864bb84aSNikita Popov; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[P_INC:%.*]], [[LATCH:%.*]] ], [ [[P_BASE]], [[HEADER_PREHEADER]] ] 237261f219fSFlorian Hahn; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_INC:%.*]], [[LATCH]] ], [ 0, [[HEADER_PREHEADER]] ] 238261f219fSFlorian Hahn; CHECK-NEXT: [[I_INC]] = add nuw nsw i64 [[I]], 1 239261f219fSFlorian Hahn; CHECK-NEXT: [[I_UGE_EXT:%.*]] = icmp uge i64 [[I]], [[EXT]] 240261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[I_UGE_EXT]], label [[TRAP_LOOPEXIT:%.*]], label [[LATCH]] 241261f219fSFlorian Hahn; CHECK: latch: 242*864bb84aSNikita Popov; CHECK-NEXT: [[P_INC]] = getelementptr inbounds i32, ptr [[P]], i64 1 243*864bb84aSNikita Popov; CHECK-NEXT: [[C:%.*]] = icmp ne ptr [[P_INC]], [[P_END]] 244*864bb84aSNikita Popov; CHECK-NEXT: store i32 0, ptr [[P]], align 4 245261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[HEADER]], label [[EXIT:%.*]] 246261f219fSFlorian Hahn; CHECK: exit: 247261f219fSFlorian Hahn; CHECK-NEXT: ret i1 true 248261f219fSFlorian Hahn; 249261f219fSFlorian Hahnentry: 250261f219fSFlorian Hahn %ext = zext i32 %len to i64 251*864bb84aSNikita Popov %p.end = getelementptr inbounds i32, ptr %p.base, i64 %ext 252261f219fSFlorian Hahn %len.nonzero = icmp ne i32 %len, 0 253261f219fSFlorian Hahn br i1 %len.nonzero, label %header, label %trap 254261f219fSFlorian Hahn 255261f219fSFlorian Hahntrap: 256261f219fSFlorian Hahn ret i1 false 257261f219fSFlorian Hahn 258261f219fSFlorian Hahnheader: 259*864bb84aSNikita Popov %p = phi ptr [ %p.base, %entry ], [ %p.inc, %latch ] 260261f219fSFlorian Hahn %i = phi i64 [ 0, %entry ], [ %i.inc, %latch] 261261f219fSFlorian Hahn %i.inc = add nsw nuw i64 %i, 1 262261f219fSFlorian Hahn %i.uge.ext = icmp uge i64 %i, %ext 263261f219fSFlorian Hahn br i1 %i.uge.ext, label %trap, label %latch 264261f219fSFlorian Hahn 265261f219fSFlorian Hahnlatch: 266*864bb84aSNikita Popov %p.inc = getelementptr inbounds i32, ptr %p, i64 1 267*864bb84aSNikita Popov %c = icmp ne ptr %p.inc, %p.end 268*864bb84aSNikita Popov store i32 0, ptr %p 269261f219fSFlorian Hahn br i1 %c, label %header, label %exit 270261f219fSFlorian Hahn 271261f219fSFlorian Hahnexit: 272261f219fSFlorian Hahn ret i1 true 273261f219fSFlorian Hahn} 274261f219fSFlorian Hahn 275*864bb84aSNikita Popovdefine i1 @cannot_simplify_uge_i32_ptr_len(ptr %p.base, i64 %len) { 276261f219fSFlorian Hahn; CHECK-LABEL: @cannot_simplify_uge_i32_ptr_len( 277261f219fSFlorian Hahn; CHECK-NEXT: entry: 278*864bb84aSNikita Popov; CHECK-NEXT: [[P_END:%.*]] = getelementptr inbounds i32, ptr [[P_BASE:%.*]], i64 [[LEN:%.*]] 279261f219fSFlorian Hahn; CHECK-NEXT: [[LEN_NONZERO:%.*]] = icmp ne i64 [[LEN]], 0 280261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NONZERO]], label [[HEADER_PREHEADER:%.*]], label [[TRAP:%.*]] 281261f219fSFlorian Hahn; CHECK: header.preheader: 282261f219fSFlorian Hahn; CHECK-NEXT: br label [[HEADER:%.*]] 283261f219fSFlorian Hahn; CHECK: trap.loopexit: 284261f219fSFlorian Hahn; CHECK-NEXT: br label [[TRAP]] 285261f219fSFlorian Hahn; CHECK: trap: 286261f219fSFlorian Hahn; CHECK-NEXT: ret i1 false 287261f219fSFlorian Hahn; CHECK: header: 288*864bb84aSNikita Popov; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[P_INC:%.*]], [[LATCH:%.*]] ], [ [[P_BASE]], [[HEADER_PREHEADER]] ] 289261f219fSFlorian Hahn; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_INC:%.*]], [[LATCH]] ], [ 0, [[HEADER_PREHEADER]] ] 290261f219fSFlorian Hahn; CHECK-NEXT: [[I_INC]] = add nuw nsw i64 [[I]], 1 291261f219fSFlorian Hahn; CHECK-NEXT: [[I_UGE_EXT:%.*]] = icmp uge i64 [[I]], [[LEN]] 292261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[I_UGE_EXT]], label [[TRAP_LOOPEXIT:%.*]], label [[LATCH]] 293261f219fSFlorian Hahn; CHECK: latch: 294*864bb84aSNikita Popov; CHECK-NEXT: [[P_INC]] = getelementptr inbounds i32, ptr [[P]], i64 1 295*864bb84aSNikita Popov; CHECK-NEXT: [[C:%.*]] = icmp ne ptr [[P_INC]], [[P_END]] 296*864bb84aSNikita Popov; CHECK-NEXT: store i32 0, ptr [[P]], align 4 297261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[HEADER]], label [[EXIT:%.*]] 298261f219fSFlorian Hahn; CHECK: exit: 299261f219fSFlorian Hahn; CHECK-NEXT: ret i1 true 300261f219fSFlorian Hahn; 301261f219fSFlorian Hahnentry: 302*864bb84aSNikita Popov %p.end = getelementptr inbounds i32, ptr %p.base, i64 %len 303261f219fSFlorian Hahn %len.nonzero = icmp ne i64 %len, 0 304261f219fSFlorian Hahn br i1 %len.nonzero, label %header, label %trap 305261f219fSFlorian Hahn 306261f219fSFlorian Hahntrap: 307261f219fSFlorian Hahn ret i1 false 308261f219fSFlorian Hahn 309261f219fSFlorian Hahnheader: 310*864bb84aSNikita Popov %p = phi ptr [ %p.base, %entry ], [ %p.inc, %latch ] 311261f219fSFlorian Hahn %i = phi i64 [ 0, %entry ], [ %i.inc, %latch] 312261f219fSFlorian Hahn %i.inc = add nsw nuw i64 %i, 1 313261f219fSFlorian Hahn %i.uge.ext = icmp uge i64 %i, %len 314261f219fSFlorian Hahn br i1 %i.uge.ext, label %trap, label %latch 315261f219fSFlorian Hahn 316261f219fSFlorian Hahnlatch: 317*864bb84aSNikita Popov %p.inc = getelementptr inbounds i32, ptr %p, i64 1 318*864bb84aSNikita Popov %c = icmp ne ptr %p.inc, %p.end 319*864bb84aSNikita Popov store i32 0, ptr %p 320261f219fSFlorian Hahn br i1 %c, label %header, label %exit 321261f219fSFlorian Hahn 322261f219fSFlorian Hahnexit: 323261f219fSFlorian Hahn ret i1 true 324261f219fSFlorian Hahn} 325261f219fSFlorian Hahn 326*864bb84aSNikita Popovdefine i1 @cannot_simplify_uge_i32_ptr_len_zext_step_2(ptr %p.base, i32 %len) { 327261f219fSFlorian Hahn; CHECK-LABEL: @cannot_simplify_uge_i32_ptr_len_zext_step_2( 328261f219fSFlorian Hahn; CHECK-NEXT: entry: 329261f219fSFlorian Hahn; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[LEN:%.*]] to i64 330*864bb84aSNikita Popov; CHECK-NEXT: [[P_END:%.*]] = getelementptr inbounds i32, ptr [[P_BASE:%.*]], i64 [[EXT]] 331261f219fSFlorian Hahn; CHECK-NEXT: [[LEN_NONZERO:%.*]] = icmp ne i32 [[LEN]], 0 332261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NONZERO]], label [[HEADER_PREHEADER:%.*]], label [[TRAP:%.*]] 333261f219fSFlorian Hahn; CHECK: header.preheader: 334261f219fSFlorian Hahn; CHECK-NEXT: br label [[HEADER:%.*]] 335261f219fSFlorian Hahn; CHECK: trap.loopexit: 336261f219fSFlorian Hahn; CHECK-NEXT: br label [[TRAP]] 337261f219fSFlorian Hahn; CHECK: trap: 338261f219fSFlorian Hahn; CHECK-NEXT: ret i1 false 339261f219fSFlorian Hahn; CHECK: header: 340*864bb84aSNikita Popov; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[P_INC:%.*]], [[LATCH:%.*]] ], [ [[P_BASE]], [[HEADER_PREHEADER]] ] 341261f219fSFlorian Hahn; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_INC:%.*]], [[LATCH]] ], [ 0, [[HEADER_PREHEADER]] ] 342261f219fSFlorian Hahn; CHECK-NEXT: [[I_INC]] = add nuw nsw i64 [[I]], 2 343261f219fSFlorian Hahn; CHECK-NEXT: [[I_UGE_EXT:%.*]] = icmp uge i64 [[I]], [[EXT]] 344261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[I_UGE_EXT]], label [[TRAP_LOOPEXIT:%.*]], label [[LATCH]] 345261f219fSFlorian Hahn; CHECK: latch: 346*864bb84aSNikita Popov; CHECK-NEXT: [[P_INC]] = getelementptr inbounds i32, ptr [[P]], i64 1 347*864bb84aSNikita Popov; CHECK-NEXT: [[C:%.*]] = icmp ne ptr [[P_INC]], [[P_END]] 348*864bb84aSNikita Popov; CHECK-NEXT: store i32 0, ptr [[P]], align 4 349261f219fSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[HEADER]], label [[EXIT:%.*]] 350261f219fSFlorian Hahn; CHECK: exit: 351261f219fSFlorian Hahn; CHECK-NEXT: ret i1 true 352261f219fSFlorian Hahn; 353261f219fSFlorian Hahnentry: 354261f219fSFlorian Hahn %ext = zext i32 %len to i64 355*864bb84aSNikita Popov %p.end = getelementptr inbounds i32, ptr %p.base, i64 %ext 356261f219fSFlorian Hahn %len.nonzero = icmp ne i32 %len, 0 357261f219fSFlorian Hahn br i1 %len.nonzero, label %header, label %trap 358261f219fSFlorian Hahn 359261f219fSFlorian Hahntrap: 360261f219fSFlorian Hahn ret i1 false 361261f219fSFlorian Hahn 362261f219fSFlorian Hahnheader: 363*864bb84aSNikita Popov %p = phi ptr [ %p.base, %entry ], [ %p.inc, %latch ] 364261f219fSFlorian Hahn %i = phi i64 [ 0, %entry ], [ %i.inc, %latch] 365261f219fSFlorian Hahn %i.inc = add nsw nuw i64 %i, 2 366261f219fSFlorian Hahn %i.uge.ext = icmp uge i64 %i, %ext 367261f219fSFlorian Hahn br i1 %i.uge.ext, label %trap, label %latch 368261f219fSFlorian Hahn 369261f219fSFlorian Hahnlatch: 370*864bb84aSNikita Popov %p.inc = getelementptr inbounds i32, ptr %p, i64 1 371*864bb84aSNikita Popov %c = icmp ne ptr %p.inc, %p.end 372*864bb84aSNikita Popov store i32 0, ptr %p 373261f219fSFlorian Hahn br i1 %c, label %header, label %exit 374261f219fSFlorian Hahn 375261f219fSFlorian Hahnexit: 376261f219fSFlorian Hahn ret i1 true 377261f219fSFlorian Hahn} 378