1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s 3 4target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 5 6define i1 @test_outer_gep_last_index_no_overflow_all_inbounds_1(ptr %dst) { 7; CHECK-LABEL: @test_outer_gep_last_index_no_overflow_all_inbounds_1( 8; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 0 9; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 2 10; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST_0]], i64 1, i64 1 11; CHECK-NEXT: ret i1 true 12; 13 %dst.0 = getelementptr inbounds ptr, ptr %dst, i64 0 14 %upper = getelementptr inbounds ptr, ptr %dst, i64 2 15 %gep.1 = getelementptr inbounds [2 x i32] , ptr %dst.0, i64 1, i64 1 16 %c.1 = icmp ult ptr %gep.1, %upper 17 ret i1 %c.1 18} 19 20define i1 @test_outer_gep_last_index_no_overflow_all_inbounds_2(ptr %dst) { 21; CHECK-LABEL: @test_outer_gep_last_index_no_overflow_all_inbounds_2( 22; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 0 23; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 3 24; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST_0]], i64 1, i64 1 25; CHECK-NEXT: ret i1 true 26; 27 %dst.0 = getelementptr inbounds ptr, ptr %dst, i64 0 28 %upper = getelementptr inbounds ptr, ptr %dst, i64 3 29 %gep.1 = getelementptr inbounds [2 x i32] , ptr %dst.0, i64 1, i64 1 30 %c.1 = icmp ult ptr %gep.1, %upper 31 ret i1 %c.1 32} 33 34define i1 @test_outer_gep_last_index_overflow_all_inbounds(ptr %dst) { 35; CHECK-LABEL: @test_outer_gep_last_index_overflow_all_inbounds( 36; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 0 37; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 2 38; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST_0]], i64 1, i64 2 39; CHECK-NEXT: ret i1 false 40; 41 %dst.0 = getelementptr inbounds ptr, ptr %dst, i64 0 42 %upper = getelementptr inbounds ptr, ptr %dst, i64 2 43 %gep.1 = getelementptr inbounds [2 x i32] , ptr %dst.0, i64 1, i64 2 44 %c = icmp ult ptr %gep.1, %upper 45 ret i1 %c 46} 47 48define i1 @test_inner_gep_multiple_indices_ult_true_all_inbounds(ptr %dst) { 49; CHECK-LABEL: @test_inner_gep_multiple_indices_ult_true_all_inbounds( 50; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0 51; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2 52; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1 53; CHECK-NEXT: ret i1 true 54; 55 %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0 56 %upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2 57 %gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1 58 %c = icmp ult ptr %gep.1, %upper 59 ret i1 %c 60} 61 62define i1 @test_inner_gep_multiple_indices_uge_true_all_inbounds(ptr %dst) { 63; CHECK-LABEL: @test_inner_gep_multiple_indices_uge_true_all_inbounds( 64; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0 65; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2 66; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1 67; CHECK-NEXT: ret i1 true 68; 69 %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0 70 %upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2 71 %gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1 72 %c = icmp uge ptr %gep.1, %dst.0 73 ret i1 %c 74} 75 76define i1 @test_inner_gep_multiple_indices_ult_false_all_inbounds(ptr %dst) { 77; CHECK-LABEL: @test_inner_gep_multiple_indices_ult_false_all_inbounds( 78; CHECK-NEXT: entry: 79; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0 80; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2 81; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 2 82; CHECK-NEXT: ret i1 false 83; 84entry: 85 %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0 86 %upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2 87 %gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 2 88 %c = icmp ult ptr %gep.1, %upper 89 ret i1 %c 90} 91 92define i1 @test_inner_gep_multiple_indices_uge_true_all_inbounds_2(ptr %dst) { 93; CHECK-LABEL: @test_inner_gep_multiple_indices_uge_true_all_inbounds_2( 94; CHECK-NEXT: entry: 95; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0 96; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2 97; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 2 98; CHECK-NEXT: ret i1 true 99; 100entry: 101 %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0 102 %upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2 103 %gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 2 104 %c = icmp uge ptr %gep.1, %dst.0 105 ret i1 %c 106} 107 108define i1 @test_inner_gep_multiple_indices_ult_true_inc_gep_all_inbounds_overflow(ptr %dst) { 109; CHECK-LABEL: @test_inner_gep_multiple_indices_ult_true_inc_gep_all_inbounds_overflow( 110; CHECK-NEXT: entry: 111; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0 112; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 6 113; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[DST_0]], i64 2 114; CHECK-NEXT: [[C:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]] 115; CHECK-NEXT: ret i1 [[C]] 116; 117entry: 118 %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0 119 %upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 6 120 %gep.1 = getelementptr i32, ptr %dst.0, i64 2 121 %c = icmp ult ptr %gep.1, %upper 122 ret i1 %c 123} 124 125define i1 @test_inner_gep_multiple_indices_ult_true_inc_gep_not_inbounds(ptr %dst) { 126; CHECK-LABEL: @test_inner_gep_multiple_indices_ult_true_inc_gep_not_inbounds( 127; CHECK-NEXT: entry: 128; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0 129; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2 130; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[DST_0]], i64 1 131; CHECK-NEXT: [[C:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]] 132; CHECK-NEXT: ret i1 [[C]] 133; 134entry: 135 %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0 136 %upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2 137 %gep.1 = getelementptr i32, ptr %dst.0, i64 1 138 %c = icmp ult ptr %gep.1, %upper 139 ret i1 %c 140} 141 142define i1 @test_inner_gep_multiple_indices_uge_true_inc_gep_not_inbounds(ptr %dst) { 143; CHECK-LABEL: @test_inner_gep_multiple_indices_uge_true_inc_gep_not_inbounds( 144; CHECK-NEXT: entry: 145; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0 146; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2 147; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[DST_0]], i64 1 148; CHECK-NEXT: [[C:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]] 149; CHECK-NEXT: ret i1 [[C]] 150; 151entry: 152 %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0 153 %upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2 154 %gep.1 = getelementptr i32, ptr %dst.0, i64 1 155 %c = icmp ult ptr %gep.1, %upper 156 ret i1 %c 157} 158 159define i1 @test_inner_gep_multiple_indices_ult_false_inc_gep_not_inbounds(ptr %dst) { 160; CHECK-LABEL: @test_inner_gep_multiple_indices_ult_false_inc_gep_not_inbounds( 161; CHECK-NEXT: entry: 162; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0 163; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2 164; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[DST_0]], i64 2 165; CHECK-NEXT: [[C:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]] 166; CHECK-NEXT: ret i1 [[C]] 167; 168entry: 169 %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0 170 %upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2 171 %gep.1 = getelementptr i32, ptr %dst.0, i64 2 172 %c = icmp ult ptr %gep.1, %upper 173 ret i1 %c 174} 175 176define i1 @test_inner_gep_multiple_indices_ult_true_inc_gep_not_inbounds_overflow(ptr %dst) { 177; CHECK-LABEL: @test_inner_gep_multiple_indices_ult_true_inc_gep_not_inbounds_overflow( 178; CHECK-NEXT: entry: 179; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0 180; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 5 181; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[DST_0]], i64 2 182; CHECK-NEXT: [[C:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]] 183; CHECK-NEXT: ret i1 [[C]] 184; 185entry: 186 %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0 187 %upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 5 188 %gep.1 = getelementptr i32, ptr %dst.0, i64 2 189 %c = icmp ult ptr %gep.1, %upper 190 ret i1 %c 191} 192 193define i1 @test_inner_gep_multi_index(ptr %dst) { 194; CHECK-LABEL: @test_inner_gep_multi_index( 195; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 0 196; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 2 197; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST_0]], i64 1, i64 1 198; CHECK-NEXT: ret i1 true 199; 200 %dst.0 = getelementptr inbounds ptr, ptr %dst, i64 0 201 %upper = getelementptr inbounds ptr, ptr %dst, i64 2 202 %gep.1 = getelementptr inbounds [2 x i32] , ptr %dst.0, i64 1, i64 1 203 %c.1 = icmp ult ptr %gep.1, %upper 204 ret i1 %c.1 205} 206 207define i1 @test_inner_gep_multi_index_outer_gep_last_index_no_overflow_all_inbounds(ptr %dst) { 208; CHECK-LABEL: @test_inner_gep_multi_index_outer_gep_last_index_no_overflow_all_inbounds( 209; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0 210; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 2 211; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST_0]], i64 1, i64 1 212; CHECK-NEXT: ret i1 true 213; 214 %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0 215 %upper = getelementptr inbounds ptr, ptr %dst, i64 2 216 %gep.1 = getelementptr inbounds [2 x i32] , ptr %dst.0, i64 1, i64 1 217 %c.1 = icmp ult ptr %gep.1, %upper 218 ret i1 %c.1 219} 220 221define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_1(ptr %dst) { 222; CHECK-LABEL: @test_inner_gep_multi_index_no_overflow_all_inbounds_1( 223; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 1 224; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 2 225; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1 226; CHECK-NEXT: ret i1 false 227; 228 %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 1 229 %upper = getelementptr inbounds i32, ptr %dst, i64 2 230 %gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1 231 %c.1 = icmp ult ptr %gep.1, %upper 232 ret i1 %c.1 233} 234 235define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_2(ptr %dst) { 236; CHECK-LABEL: @test_inner_gep_multi_index_no_overflow_all_inbounds_2( 237; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 1, i64 0 238; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 2 239; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1 240; CHECK-NEXT: ret i1 false 241; 242 %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 1, i64 0 243 %upper = getelementptr inbounds i32, ptr %dst, i64 2 244 %gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1 245 %c.1 = icmp ult ptr %gep.1, %upper 246 ret i1 %c.1 247} 248 249define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_3(ptr %dst) { 250; CHECK-LABEL: @test_inner_gep_multi_index_no_overflow_all_inbounds_3( 251; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 1, i64 0 252; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 3 253; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1 254; CHECK-NEXT: ret i1 false 255; 256 %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 1, i64 0 257 %upper = getelementptr inbounds i32, ptr %dst, i64 3 258 %gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1 259 %c.1 = icmp ult ptr %gep.1, %upper 260 ret i1 %c.1 261} 262 263define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_4(ptr %dst) { 264; CHECK-LABEL: @test_inner_gep_multi_index_no_overflow_all_inbounds_4( 265; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 1, i64 0 266; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 4 267; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1 268; CHECK-NEXT: ret i1 true 269; 270 %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 1, i64 0 271 %upper = getelementptr inbounds i32, ptr %dst, i64 4 272 %gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1 273 %c.1 = icmp ult ptr %gep.1, %upper 274 ret i1 %c.1 275} 276 277define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_5(i64 %off, ptr %dst) { 278; CHECK-LABEL: @test_inner_gep_multi_index_no_overflow_all_inbounds_5( 279; CHECK-NEXT: [[OFF_ULT:%.*]] = icmp ule i64 [[OFF:%.*]], 2 280; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 2, i64 0 281; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 5 282; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1 283; CHECK-NEXT: ret i1 true 284; 285 %off.ult = icmp ule i64 %off, 2 286 %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 2, i64 0 287 %upper = getelementptr inbounds i32, ptr %dst, i64 5 288 %gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1 289 %c.1 = icmp ule ptr %gep.1, %upper 290 ret i1 %c.1 291} 292 293define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_6(i64 %off, ptr %dst) { 294; CHECK-LABEL: @test_inner_gep_multi_index_no_overflow_all_inbounds_6( 295; CHECK-NEXT: [[OFF_ULT:%.*]] = icmp ule i64 [[OFF:%.*]], 2 296; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 2, i64 0 297; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 5 298; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1 299; CHECK-NEXT: ret i1 false 300; 301 %off.ult = icmp ule i64 %off, 2 302 %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 2, i64 0 303 %upper = getelementptr inbounds i32, ptr %dst, i64 5 304 %gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1 305 %c.1 = icmp ult ptr %gep.1, %upper 306 ret i1 %c.1 307} 308 309define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_7(i64 %off, ptr %dst) { 310; CHECK-LABEL: @test_inner_gep_multi_index_no_overflow_all_inbounds_7( 311; CHECK-NEXT: [[OFF_ULT:%.*]] = icmp ule i64 [[OFF:%.*]], 2 312; CHECK-NEXT: [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 2, i64 0 313; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[OFF]] 314; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1 315; CHECK-NEXT: [[C_1:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]] 316; CHECK-NEXT: ret i1 [[C_1]] 317; 318 %off.ult = icmp ule i64 %off, 2 319 %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 2, i64 0 320 %upper = getelementptr inbounds i32, ptr %dst, i64 %off 321 %gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1 322 %c.1 = icmp ult ptr %gep.1, %upper 323 ret i1 %c.1 324} 325