1175d68ddSFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 227d1d8bcSRoman Lebedev; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s 3175d68ddSFlorian Hahn 4175d68ddSFlorian Hahn; Tests for using inbounds information from GEPs where the GEP only causes UB in the use blocks. 5175d68ddSFlorian Hahn 6*34e477e9SFlorian Hahndeclare void @noundef(ptr noundef) willreturn nounwind 7*34e477e9SFlorian Hahndeclare void @noundef2(ptr noundef) 8175d68ddSFlorian Hahn 9175d68ddSFlorian Hahndeclare void @use(i1) 10175d68ddSFlorian Hahn 11175d68ddSFlorian Hahn; %start + %n.ext is guaranteed to not overflow (due to inbounds). 12175d68ddSFlorian Hahn; %start + %idx.ext does not overflow if %idx.ext <= %n.ext. 13*34e477e9SFlorian Hahndefine i1 @inbounds_poison_is_ub_in_use_block_1(ptr %src, i32 %n, i32 %idx) { 14175d68ddSFlorian Hahn; CHECK-LABEL: @inbounds_poison_is_ub_in_use_block_1( 15175d68ddSFlorian Hahn; CHECK-NEXT: entry: 16175d68ddSFlorian Hahn; CHECK-NEXT: [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64 17*34e477e9SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[N_EXT]] 18175d68ddSFlorian Hahn; CHECK-NEXT: [[CMP_IDX:%.*]] = icmp ult i32 [[IDX:%.*]], [[N]] 19175d68ddSFlorian Hahn; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64 20*34e477e9SFlorian Hahn; CHECK-NEXT: [[SRC_IDX:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IDX_EXT]] 21175d68ddSFlorian Hahn; CHECK-NEXT: br i1 [[CMP_IDX]], label [[THEN:%.*]], label [[ELSE:%.*]] 22175d68ddSFlorian Hahn; CHECK: then: 23*34e477e9SFlorian Hahn; CHECK-NEXT: call void @noundef(ptr [[UPPER]]) 24*34e477e9SFlorian Hahn; CHECK-NEXT: [[CMP_UPPER_1:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]] 25175d68ddSFlorian Hahn; CHECK-NEXT: ret i1 [[CMP_UPPER_1]] 26175d68ddSFlorian Hahn; CHECK: else: 27*34e477e9SFlorian Hahn; CHECK-NEXT: [[CMP_UPPER_2:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]] 28175d68ddSFlorian Hahn; CHECK-NEXT: ret i1 [[CMP_UPPER_2]] 29175d68ddSFlorian Hahn; 30175d68ddSFlorian Hahnentry: 31175d68ddSFlorian Hahn %n.ext = zext i32 %n to i64 32*34e477e9SFlorian Hahn %upper = getelementptr inbounds i32, ptr %src, i64 %n.ext 33175d68ddSFlorian Hahn %cmp.idx = icmp ult i32 %idx, %n 34175d68ddSFlorian Hahn %idx.ext = zext i32 %idx to i64 35*34e477e9SFlorian Hahn %src.idx = getelementptr i32, ptr %src, i64 %idx.ext 36175d68ddSFlorian Hahn br i1 %cmp.idx, label %then, label %else 37175d68ddSFlorian Hahn 38175d68ddSFlorian Hahnthen: 39*34e477e9SFlorian Hahn call void @noundef(ptr %upper) 40*34e477e9SFlorian Hahn %cmp.upper.1 = icmp ule ptr %src.idx, %upper 41175d68ddSFlorian Hahn ret i1 %cmp.upper.1 42175d68ddSFlorian Hahn 43175d68ddSFlorian Hahnelse: 44*34e477e9SFlorian Hahn %cmp.upper.2 = icmp ule ptr %src.idx, %upper 45175d68ddSFlorian Hahn ret i1 %cmp.upper.2 46175d68ddSFlorian Hahn} 47175d68ddSFlorian Hahn 48*34e477e9SFlorian Hahndefine i1 @inbounds_poison_is_ub_in_use_block_2(ptr %src, i32 %n, i32 %idx, i1 %c) { 49175d68ddSFlorian Hahn; CHECK-LABEL: @inbounds_poison_is_ub_in_use_block_2( 50175d68ddSFlorian Hahn; CHECK-NEXT: entry: 51175d68ddSFlorian Hahn; CHECK-NEXT: [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64 52*34e477e9SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[N_EXT]] 53175d68ddSFlorian Hahn; CHECK-NEXT: [[CMP_IDX:%.*]] = icmp ult i32 [[IDX:%.*]], [[N]] 54175d68ddSFlorian Hahn; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64 55*34e477e9SFlorian Hahn; CHECK-NEXT: [[SRC_IDX:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IDX_EXT]] 56175d68ddSFlorian Hahn; CHECK-NEXT: br i1 [[CMP_IDX]], label [[THEN:%.*]], label [[ELSE:%.*]] 57175d68ddSFlorian Hahn; CHECK: then: 58*34e477e9SFlorian Hahn; CHECK-NEXT: [[CMP_UPPER_1:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]] 59*34e477e9SFlorian Hahn; CHECK-NEXT: call void @noundef(ptr [[UPPER]]) 60175d68ddSFlorian Hahn; CHECK-NEXT: ret i1 [[CMP_UPPER_1]] 61175d68ddSFlorian Hahn; CHECK: else: 62*34e477e9SFlorian Hahn; CHECK-NEXT: [[CMP_UPPER_2:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]] 63175d68ddSFlorian Hahn; CHECK-NEXT: ret i1 [[CMP_UPPER_2]] 64175d68ddSFlorian Hahn; 65175d68ddSFlorian Hahnentry: 66175d68ddSFlorian Hahn %n.ext = zext i32 %n to i64 67*34e477e9SFlorian Hahn %upper = getelementptr inbounds i32, ptr %src, i64 %n.ext 68175d68ddSFlorian Hahn %cmp.idx = icmp ult i32 %idx, %n 69175d68ddSFlorian Hahn %idx.ext = zext i32 %idx to i64 70*34e477e9SFlorian Hahn %src.idx = getelementptr i32, ptr %src, i64 %idx.ext 71175d68ddSFlorian Hahn br i1 %cmp.idx, label %then, label %else 72175d68ddSFlorian Hahn 73175d68ddSFlorian Hahnthen: 74*34e477e9SFlorian Hahn %cmp.upper.1 = icmp ule ptr %src.idx, %upper 75*34e477e9SFlorian Hahn call void @noundef(ptr %upper) 76175d68ddSFlorian Hahn ret i1 %cmp.upper.1 77175d68ddSFlorian Hahn 78175d68ddSFlorian Hahnelse: 79*34e477e9SFlorian Hahn %cmp.upper.2 = icmp ule ptr %src.idx, %upper 80175d68ddSFlorian Hahn ret i1 %cmp.upper.2 81175d68ddSFlorian Hahn} 82175d68ddSFlorian Hahn 83175d68ddSFlorian Hahndeclare void @llvm.assume(i1) 84175d68ddSFlorian Hahn 85175d68ddSFlorian Hahn; %start + %n.ext is guaranteed to not overflow (due to inbounds). 86175d68ddSFlorian Hahn; %start + %idx.ext does not overflow if %idx.ext <= %n.ext. 87*34e477e9SFlorian Hahndefine i1 @inbounds_poison_is_ub_in_use_block_by_assume(ptr %src, i32 %n, i32 %idx) { 88175d68ddSFlorian Hahn; CHECK-LABEL: @inbounds_poison_is_ub_in_use_block_by_assume( 89175d68ddSFlorian Hahn; CHECK-NEXT: entry: 90175d68ddSFlorian Hahn; CHECK-NEXT: [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64 91*34e477e9SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[N_EXT]] 92175d68ddSFlorian Hahn; CHECK-NEXT: [[CMP_IDX:%.*]] = icmp ult i32 [[IDX:%.*]], [[N]] 93175d68ddSFlorian Hahn; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64 94*34e477e9SFlorian Hahn; CHECK-NEXT: [[SRC_IDX:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IDX_EXT]] 95175d68ddSFlorian Hahn; CHECK-NEXT: br i1 [[CMP_IDX]], label [[THEN:%.*]], label [[ELSE:%.*]] 96175d68ddSFlorian Hahn; CHECK: then: 97*34e477e9SFlorian Hahn; CHECK-NEXT: [[CMP_NE:%.*]] = icmp ule ptr null, [[UPPER]] 98175d68ddSFlorian Hahn; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_NE]]) 99*34e477e9SFlorian Hahn; CHECK-NEXT: [[CMP_UPPER_1:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]] 100175d68ddSFlorian Hahn; CHECK-NEXT: ret i1 [[CMP_UPPER_1]] 101175d68ddSFlorian Hahn; CHECK: else: 102*34e477e9SFlorian Hahn; CHECK-NEXT: [[CMP_UPPER_2:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]] 103175d68ddSFlorian Hahn; CHECK-NEXT: ret i1 [[CMP_UPPER_2]] 104175d68ddSFlorian Hahn; 105175d68ddSFlorian Hahnentry: 106175d68ddSFlorian Hahn %n.ext = zext i32 %n to i64 107*34e477e9SFlorian Hahn %upper = getelementptr inbounds i32, ptr %src, i64 %n.ext 108175d68ddSFlorian Hahn %cmp.idx = icmp ult i32 %idx, %n 109175d68ddSFlorian Hahn %idx.ext = zext i32 %idx to i64 110*34e477e9SFlorian Hahn %src.idx = getelementptr i32, ptr %src, i64 %idx.ext 111175d68ddSFlorian Hahn br i1 %cmp.idx, label %then, label %else 112175d68ddSFlorian Hahn 113175d68ddSFlorian Hahnthen: 114*34e477e9SFlorian Hahn %cmp.ne = icmp ule ptr null, %upper 115175d68ddSFlorian Hahn call void @llvm.assume(i1 %cmp.ne) 116*34e477e9SFlorian Hahn %cmp.upper.1 = icmp ule ptr %src.idx, %upper 117175d68ddSFlorian Hahn ret i1 %cmp.upper.1 118175d68ddSFlorian Hahn 119175d68ddSFlorian Hahnelse: 120*34e477e9SFlorian Hahn %cmp.upper.2 = icmp ule ptr %src.idx, %upper 121175d68ddSFlorian Hahn ret i1 %cmp.upper.2 122175d68ddSFlorian Hahn} 123175d68ddSFlorian Hahn 124175d68ddSFlorian Hahn 125175d68ddSFlorian Hahn; %start + %n.ext is guaranteed to not overflow (due to inbounds). 126175d68ddSFlorian Hahn; %start + %idx.ext does not overflow if %idx.ext <= %n.ext. 127*34e477e9SFlorian Hahndefine i1 @inbounds_poison_is_ub_in_in_multiple_use_blocks_1(ptr %src, i32 %n, i32 %idx, i1 %c) { 128175d68ddSFlorian Hahn; CHECK-LABEL: @inbounds_poison_is_ub_in_in_multiple_use_blocks_1( 129175d68ddSFlorian Hahn; CHECK-NEXT: entry: 130175d68ddSFlorian Hahn; CHECK-NEXT: [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64 131*34e477e9SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[N_EXT]] 132175d68ddSFlorian Hahn; CHECK-NEXT: br i1 [[C:%.*]], label [[CHECK_BB:%.*]], label [[EXIT:%.*]] 133175d68ddSFlorian Hahn; CHECK: check.bb: 134*34e477e9SFlorian Hahn; CHECK-NEXT: call void @noundef(ptr [[UPPER]]) 135175d68ddSFlorian Hahn; CHECK-NEXT: [[CMP_IDX:%.*]] = icmp ult i32 [[IDX:%.*]], [[N]] 136175d68ddSFlorian Hahn; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64 137*34e477e9SFlorian Hahn; CHECK-NEXT: [[SRC_IDX:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IDX_EXT]] 138175d68ddSFlorian Hahn; CHECK-NEXT: br i1 [[CMP_IDX]], label [[THEN:%.*]], label [[ELSE:%.*]] 139175d68ddSFlorian Hahn; CHECK: then: 140*34e477e9SFlorian Hahn; CHECK-NEXT: call void @noundef(ptr [[UPPER]]) 141*34e477e9SFlorian Hahn; CHECK-NEXT: [[CMP_UPPER_1:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]] 142175d68ddSFlorian Hahn; CHECK-NEXT: ret i1 [[CMP_UPPER_1]] 143175d68ddSFlorian Hahn; CHECK: else: 144*34e477e9SFlorian Hahn; CHECK-NEXT: [[CMP_UPPER_2:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]] 145175d68ddSFlorian Hahn; CHECK-NEXT: ret i1 [[CMP_UPPER_2]] 146175d68ddSFlorian Hahn; CHECK: exit: 147175d68ddSFlorian Hahn; CHECK-NEXT: ret i1 false 148175d68ddSFlorian Hahn; 149175d68ddSFlorian Hahnentry: 150175d68ddSFlorian Hahn %n.ext = zext i32 %n to i64 151*34e477e9SFlorian Hahn %upper = getelementptr inbounds i32, ptr %src, i64 %n.ext 152175d68ddSFlorian Hahn br i1 %c, label %check.bb, label %exit 153175d68ddSFlorian Hahn 154175d68ddSFlorian Hahncheck.bb: 155*34e477e9SFlorian Hahn call void @noundef(ptr %upper) 156175d68ddSFlorian Hahn %cmp.idx = icmp ult i32 %idx, %n 157175d68ddSFlorian Hahn %idx.ext = zext i32 %idx to i64 158*34e477e9SFlorian Hahn %src.idx = getelementptr i32, ptr %src, i64 %idx.ext 159175d68ddSFlorian Hahn br i1 %cmp.idx, label %then, label %else 160175d68ddSFlorian Hahn 161175d68ddSFlorian Hahnthen: 162*34e477e9SFlorian Hahn call void @noundef(ptr %upper) 163*34e477e9SFlorian Hahn %cmp.upper.1 = icmp ule ptr %src.idx, %upper 164175d68ddSFlorian Hahn ret i1 %cmp.upper.1 165175d68ddSFlorian Hahn 166175d68ddSFlorian Hahnelse: 167*34e477e9SFlorian Hahn %cmp.upper.2 = icmp ule ptr %src.idx, %upper 168175d68ddSFlorian Hahn ret i1 %cmp.upper.2 169175d68ddSFlorian Hahn 170175d68ddSFlorian Hahnexit: 171175d68ddSFlorian Hahn ret i1 false 172175d68ddSFlorian Hahn} 173175d68ddSFlorian Hahn 174*34e477e9SFlorian Hahndefine i1 @may_exit_before_ub_is_caused(ptr %src, i32 %n, i32 %idx) { 175175d68ddSFlorian Hahn; CHECK-LABEL: @may_exit_before_ub_is_caused( 176175d68ddSFlorian Hahn; CHECK-NEXT: entry: 177175d68ddSFlorian Hahn; CHECK-NEXT: [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64 178*34e477e9SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[N_EXT]] 179175d68ddSFlorian Hahn; CHECK-NEXT: [[CMP_IDX:%.*]] = icmp ult i32 [[IDX:%.*]], [[N]] 180175d68ddSFlorian Hahn; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64 181*34e477e9SFlorian Hahn; CHECK-NEXT: [[SRC_IDX:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IDX_EXT]] 182175d68ddSFlorian Hahn; CHECK-NEXT: br i1 [[CMP_IDX]], label [[THEN:%.*]], label [[ELSE:%.*]] 183175d68ddSFlorian Hahn; CHECK: then: 184*34e477e9SFlorian Hahn; CHECK-NEXT: [[CMP_UPPER_1:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]] 185175d68ddSFlorian Hahn; CHECK-NEXT: call void @use(i1 [[CMP_UPPER_1]]) 186*34e477e9SFlorian Hahn; CHECK-NEXT: call void @noundef(ptr [[UPPER]]) 187175d68ddSFlorian Hahn; CHECK-NEXT: ret i1 [[CMP_UPPER_1]] 188175d68ddSFlorian Hahn; CHECK: else: 189*34e477e9SFlorian Hahn; CHECK-NEXT: [[CMP_UPPER_2:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]] 190175d68ddSFlorian Hahn; CHECK-NEXT: ret i1 [[CMP_UPPER_2]] 191175d68ddSFlorian Hahn; 192175d68ddSFlorian Hahnentry: 193175d68ddSFlorian Hahn %n.ext = zext i32 %n to i64 194*34e477e9SFlorian Hahn %upper = getelementptr inbounds i32, ptr %src, i64 %n.ext 195175d68ddSFlorian Hahn %cmp.idx = icmp ult i32 %idx, %n 196175d68ddSFlorian Hahn %idx.ext = zext i32 %idx to i64 197*34e477e9SFlorian Hahn %src.idx = getelementptr i32, ptr %src, i64 %idx.ext 198175d68ddSFlorian Hahn br i1 %cmp.idx, label %then, label %else 199175d68ddSFlorian Hahn 200175d68ddSFlorian Hahnthen: 201*34e477e9SFlorian Hahn %cmp.upper.1 = icmp ule ptr %src.idx, %upper 202175d68ddSFlorian Hahn call void @use(i1 %cmp.upper.1); 203*34e477e9SFlorian Hahn call void @noundef(ptr %upper) 204175d68ddSFlorian Hahn ret i1 %cmp.upper.1 205175d68ddSFlorian Hahn 206175d68ddSFlorian Hahnelse: 207*34e477e9SFlorian Hahn %cmp.upper.2 = icmp ule ptr %src.idx, %upper 208175d68ddSFlorian Hahn ret i1 %cmp.upper.2 209175d68ddSFlorian Hahn} 210175d68ddSFlorian Hahn 211*34e477e9SFlorian Hahndefine i1 @only_UB_in_false_block(ptr %src, i32 %n, i32 %idx) { 212175d68ddSFlorian Hahn; CHECK-LABEL: @only_UB_in_false_block( 213175d68ddSFlorian Hahn; CHECK-NEXT: entry: 214175d68ddSFlorian Hahn; CHECK-NEXT: [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64 215*34e477e9SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[N_EXT]] 216175d68ddSFlorian Hahn; CHECK-NEXT: [[CMP_IDX:%.*]] = icmp ult i32 [[IDX:%.*]], [[N]] 217175d68ddSFlorian Hahn; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64 218*34e477e9SFlorian Hahn; CHECK-NEXT: [[SRC_IDX:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IDX_EXT]] 219175d68ddSFlorian Hahn; CHECK-NEXT: br i1 [[CMP_IDX]], label [[THEN:%.*]], label [[ELSE:%.*]] 220175d68ddSFlorian Hahn; CHECK: then: 221*34e477e9SFlorian Hahn; CHECK-NEXT: [[CMP_UPPER_1:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]] 222175d68ddSFlorian Hahn; CHECK-NEXT: ret i1 [[CMP_UPPER_1]] 223175d68ddSFlorian Hahn; CHECK: else: 224*34e477e9SFlorian Hahn; CHECK-NEXT: call void @noundef(ptr [[UPPER]]) 225*34e477e9SFlorian Hahn; CHECK-NEXT: [[CMP_UPPER_2:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]] 226175d68ddSFlorian Hahn; CHECK-NEXT: ret i1 [[CMP_UPPER_2]] 227175d68ddSFlorian Hahn; 228175d68ddSFlorian Hahnentry: 229175d68ddSFlorian Hahn %n.ext = zext i32 %n to i64 230*34e477e9SFlorian Hahn %upper = getelementptr inbounds i32, ptr %src, i64 %n.ext 231175d68ddSFlorian Hahn %cmp.idx = icmp ult i32 %idx, %n 232175d68ddSFlorian Hahn %idx.ext = zext i32 %idx to i64 233*34e477e9SFlorian Hahn %src.idx = getelementptr i32, ptr %src, i64 %idx.ext 234175d68ddSFlorian Hahn br i1 %cmp.idx, label %then, label %else 235175d68ddSFlorian Hahn 236175d68ddSFlorian Hahnthen: 237*34e477e9SFlorian Hahn %cmp.upper.1 = icmp ule ptr %src.idx, %upper 238175d68ddSFlorian Hahn ret i1 %cmp.upper.1 239175d68ddSFlorian Hahn 240175d68ddSFlorian Hahnelse: 241*34e477e9SFlorian Hahn call void @noundef(ptr %upper) 242*34e477e9SFlorian Hahn %cmp.upper.2 = icmp ule ptr %src.idx, %upper 243175d68ddSFlorian Hahn ret i1 %cmp.upper.2 244175d68ddSFlorian Hahn} 245175d68ddSFlorian Hahn 246*34e477e9SFlorian Hahndefine i1 @only_ub_by_assume_in_false_block(ptr %src, i32 %n, i32 %idx) { 247175d68ddSFlorian Hahn; CHECK-LABEL: @only_ub_by_assume_in_false_block( 248175d68ddSFlorian Hahn; CHECK-NEXT: entry: 249175d68ddSFlorian Hahn; CHECK-NEXT: [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64 250*34e477e9SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[N_EXT]] 251175d68ddSFlorian Hahn; CHECK-NEXT: [[CMP_IDX:%.*]] = icmp ult i32 [[IDX:%.*]], [[N]] 252175d68ddSFlorian Hahn; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64 253*34e477e9SFlorian Hahn; CHECK-NEXT: [[SRC_IDX:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IDX_EXT]] 254175d68ddSFlorian Hahn; CHECK-NEXT: br i1 [[CMP_IDX]], label [[THEN:%.*]], label [[ELSE:%.*]] 255175d68ddSFlorian Hahn; CHECK: then: 256*34e477e9SFlorian Hahn; CHECK-NEXT: [[CMP_UPPER_1:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]] 257175d68ddSFlorian Hahn; CHECK-NEXT: ret i1 [[CMP_UPPER_1]] 258175d68ddSFlorian Hahn; CHECK: else: 259*34e477e9SFlorian Hahn; CHECK-NEXT: [[CMP_NE:%.*]] = icmp ule ptr null, [[UPPER]] 260175d68ddSFlorian Hahn; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_NE]]) 261*34e477e9SFlorian Hahn; CHECK-NEXT: [[CMP_UPPER_2:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]] 262175d68ddSFlorian Hahn; CHECK-NEXT: ret i1 [[CMP_UPPER_2]] 263175d68ddSFlorian Hahn; 264175d68ddSFlorian Hahnentry: 265175d68ddSFlorian Hahn %n.ext = zext i32 %n to i64 266*34e477e9SFlorian Hahn %upper = getelementptr inbounds i32, ptr %src, i64 %n.ext 267175d68ddSFlorian Hahn %cmp.idx = icmp ult i32 %idx, %n 268175d68ddSFlorian Hahn %idx.ext = zext i32 %idx to i64 269*34e477e9SFlorian Hahn %src.idx = getelementptr i32, ptr %src, i64 %idx.ext 270175d68ddSFlorian Hahn br i1 %cmp.idx, label %then, label %else 271175d68ddSFlorian Hahn 272175d68ddSFlorian Hahnthen: 273*34e477e9SFlorian Hahn %cmp.upper.1 = icmp ule ptr %src.idx, %upper 274175d68ddSFlorian Hahn ret i1 %cmp.upper.1 275175d68ddSFlorian Hahn 276175d68ddSFlorian Hahnelse: 277*34e477e9SFlorian Hahn %cmp.ne = icmp ule ptr null, %upper 278175d68ddSFlorian Hahn call void @llvm.assume(i1 %cmp.ne) 279*34e477e9SFlorian Hahn %cmp.upper.2 = icmp ule ptr %src.idx, %upper 280175d68ddSFlorian Hahn ret i1 %cmp.upper.2 281175d68ddSFlorian Hahn} 282