1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes='instcombine<no-verify-fixpoint>' < %s | FileCheck %s 3 4; In the indexed_compare test the comparison is only converted int a form 5; from which we can infer non-negativity after the GEP has already been sunk 6; and revisited. 7 8define ptr @bitcast_opaque_to_opaque(ptr %a) { 9; CHECK-LABEL: @bitcast_opaque_to_opaque( 10; CHECK-NEXT: ret ptr [[A:%.*]] 11; 12 ret ptr %a 13} 14 15define ptr @bitcast_typed_to_opaque(ptr %a) { 16; CHECK-LABEL: @bitcast_typed_to_opaque( 17; CHECK-NEXT: ret ptr [[A:%.*]] 18; 19 ret ptr %a 20} 21 22define ptr @bitcast_opaque_to_typed(ptr %a) { 23; CHECK-LABEL: @bitcast_opaque_to_typed( 24; CHECK-NEXT: ret ptr [[A:%.*]] 25; 26 ret ptr %a 27} 28 29@g = global i8 0 30define ptr @bitcast_typed_to_opaque_constexpr() { 31; CHECK-LABEL: @bitcast_typed_to_opaque_constexpr( 32; CHECK-NEXT: ret ptr @g 33; 34 ret ptr @g 35} 36 37define ptr @addrspacecast_opaque_to_opaque(ptr addrspace(1) %a) { 38; CHECK-LABEL: @addrspacecast_opaque_to_opaque( 39; CHECK-NEXT: [[B:%.*]] = addrspacecast ptr addrspace(1) [[A:%.*]] to ptr 40; CHECK-NEXT: ret ptr [[B]] 41; 42 %b = addrspacecast ptr addrspace(1) %a to ptr 43 ret ptr %b 44} 45 46define ptr @addrspacecast_typed_to_opaque(ptr addrspace(1) %a) { 47; CHECK-LABEL: @addrspacecast_typed_to_opaque( 48; CHECK-NEXT: [[B:%.*]] = addrspacecast ptr addrspace(1) [[A:%.*]] to ptr 49; CHECK-NEXT: ret ptr [[B]] 50; 51 %b = addrspacecast ptr addrspace(1) %a to ptr 52 ret ptr %b 53} 54 55define ptr @addrspacecast_opaque_to_typed(ptr addrspace(1) %a) { 56; CHECK-LABEL: @addrspacecast_opaque_to_typed( 57; CHECK-NEXT: [[B:%.*]] = addrspacecast ptr addrspace(1) [[A:%.*]] to ptr 58; CHECK-NEXT: ret ptr [[B]] 59; 60 %b = addrspacecast ptr addrspace(1) %a to ptr 61 ret ptr %b 62} 63 64define ptr addrspace(1) @bitcast_and_addrspacecast_eliminable(ptr %a) { 65; CHECK-LABEL: @bitcast_and_addrspacecast_eliminable( 66; CHECK-NEXT: [[C:%.*]] = addrspacecast ptr [[A:%.*]] to ptr addrspace(1) 67; CHECK-NEXT: ret ptr addrspace(1) [[C]] 68; 69 %c = addrspacecast ptr %a to ptr addrspace(1) 70 ret ptr addrspace(1) %c 71} 72 73define ptr addrspace(1) @addrspacecast_typed_to_opaque_constexpr() { 74; CHECK-LABEL: @addrspacecast_typed_to_opaque_constexpr( 75; CHECK-NEXT: ret ptr addrspace(1) addrspacecast (ptr @g to ptr addrspace(1)) 76; 77 ret ptr addrspace(1) addrspacecast (ptr @g to ptr addrspace(1)) 78} 79 80define ptr @gep_constexpr_1(ptr %a) { 81; CHECK-LABEL: @gep_constexpr_1( 82; CHECK-NEXT: ret ptr inttoptr (i64 6 to ptr) 83; 84 ret ptr getelementptr (i16, ptr null, i32 3) 85} 86 87define ptr @gep_constexpr_2(ptr %a) { 88; CHECK-LABEL: @gep_constexpr_2( 89; CHECK-NEXT: ret ptr getelementptr (i8, ptr @g, i64 3) 90; 91 ret ptr getelementptr (i8, ptr @g, i32 3) 92} 93 94define ptr addrspace(1) @gep_constexpr_3(ptr %a) { 95; CHECK-LABEL: @gep_constexpr_3( 96; CHECK-NEXT: ret ptr addrspace(1) getelementptr (i8, ptr addrspace(1) addrspacecast (ptr @g to ptr addrspace(1)), i64 3) 97; 98 ret ptr addrspace(1) getelementptr ([0 x i8], ptr addrspace(1) addrspacecast (ptr @g to ptr addrspace(1)), i64 0, i32 3) 99} 100 101define ptr @load_bitcast_1(ptr %a) { 102; CHECK-LABEL: @load_bitcast_1( 103; CHECK-NEXT: [[B:%.*]] = load ptr, ptr [[A:%.*]], align 8 104; CHECK-NEXT: ret ptr [[B]] 105; 106 %b = load ptr, ptr %a 107 ret ptr %b 108} 109 110define ptr @load_bitcast_2(ptr %a) { 111; CHECK-LABEL: @load_bitcast_2( 112; CHECK-NEXT: [[C:%.*]] = load ptr, ptr [[A:%.*]], align 8 113; CHECK-NEXT: ret ptr [[C]] 114; 115 %c = load ptr, ptr %a 116 ret ptr %c 117} 118 119define void @call(ptr %a) { 120; CHECK-LABEL: @call( 121; CHECK-NEXT: call void [[A:%.*]]() 122; CHECK-NEXT: ret void 123; 124 call void %a() 125 ret void 126} 127 128declare void @varargs(...) 129define void @varargs_cast_typed_to_opaque_same_type(ptr %a) { 130; CHECK-LABEL: @varargs_cast_typed_to_opaque_same_type( 131; CHECK-NEXT: call void (...) @varargs(ptr byval(i32) [[A:%.*]]) 132; CHECK-NEXT: ret void 133; 134 call void (...) @varargs(ptr byval(i32) %a) 135 ret void 136} 137 138define void @varargs_cast_typed_to_opaque_different_type(ptr %a) { 139; CHECK-LABEL: @varargs_cast_typed_to_opaque_different_type( 140; CHECK-NEXT: call void (...) @varargs(ptr byval(float) [[A:%.*]]) 141; CHECK-NEXT: ret void 142; 143 call void (...) @varargs(ptr byval(float) %a) 144 ret void 145} 146 147define void @varargs_cast_typed_to_opaque_different_size(ptr %a) { 148; CHECK-LABEL: @varargs_cast_typed_to_opaque_different_size( 149; CHECK-NEXT: call void (...) @varargs(ptr byval(i64) [[A:%.*]]) 150; CHECK-NEXT: ret void 151; 152 call void (...) @varargs(ptr byval(i64) %a) 153 ret void 154} 155 156define void @varargs_cast_opaque_to_typed(ptr %a) { 157; CHECK-LABEL: @varargs_cast_opaque_to_typed( 158; CHECK-NEXT: call void (...) @varargs(ptr byval(i8) [[A:%.*]]) 159; CHECK-NEXT: ret void 160; 161 call void (...) @varargs(ptr byval(i8) %a) 162 ret void 163} 164 165define ptr @geps_combinable(ptr %a) { 166; CHECK-LABEL: @geps_combinable( 167; CHECK-NEXT: [[A3:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 8 168; CHECK-NEXT: ret ptr [[A3]] 169; 170 %a2 = getelementptr { i32, { i32, i32 } }, ptr %a, i32 0, i32 1 171 %a3 = getelementptr { i32, i32 }, ptr %a2, i32 0, i32 1 172 ret ptr %a3 173} 174 175define ptr @geps_combinable_different_elem_type1(ptr %a) { 176; CHECK-LABEL: @geps_combinable_different_elem_type1( 177; CHECK-NEXT: [[A3:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 8 178; CHECK-NEXT: ret ptr [[A3]] 179; 180 %a2 = getelementptr { i32, i32 }, ptr %a, i32 0, i32 1 181 %a3 = getelementptr { i32, i32 }, ptr %a2, i32 0, i32 1 182 ret ptr %a3 183} 184 185define ptr @geps_combinable_different_elem_type2(ptr %a) { 186; CHECK-LABEL: @geps_combinable_different_elem_type2( 187; CHECK-NEXT: [[A3:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 8 188; CHECK-NEXT: ret ptr [[A3]] 189; 190 %a2 = getelementptr { i32, i32 }, ptr %a, i32 0, i32 1 191 %a3 = getelementptr i8, ptr %a2, i64 4 192 ret ptr %a3 193} 194 195define ptr @geps_combinable_different_elem_type3(ptr %a) { 196; CHECK-LABEL: @geps_combinable_different_elem_type3( 197; CHECK-NEXT: [[A3:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 12 198; CHECK-NEXT: ret ptr [[A3]] 199; 200 %a2 = getelementptr { i32, i32 }, ptr %a, i32 0, i32 1 201 %a3 = getelementptr i8, ptr %a2, i64 8 202 ret ptr %a3 203} 204 205define ptr @geps_combinable_different_elem_type4(ptr %a) { 206; CHECK-LABEL: @geps_combinable_different_elem_type4( 207; CHECK-NEXT: [[A3:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 14 208; CHECK-NEXT: ret ptr [[A3]] 209; 210 %a2 = getelementptr { i32, i32 }, ptr %a, i32 0, i32 1 211 %a3 = getelementptr i8, ptr %a2, i64 10 212 ret ptr %a3 213} 214 215define ptr @geps_combinable_different_elem_type5(ptr %a) { 216; CHECK-LABEL: @geps_combinable_different_elem_type5( 217; CHECK-NEXT: ret ptr [[A:%.*]] 218; 219 %a2 = getelementptr { i32, i32 }, ptr %a, i32 0, i32 1 220 %a3 = getelementptr i8, ptr %a2, i64 -4 221 ret ptr %a3 222} 223 224define ptr @geps_combinable_different_elem_type6(ptr %a, i64 %idx) { 225; CHECK-LABEL: @geps_combinable_different_elem_type6( 226; CHECK-NEXT: [[A3:%.*]] = getelementptr { i32, i32 }, ptr [[A:%.*]], i64 [[IDX:%.*]], i32 1 227; CHECK-NEXT: ret ptr [[A3]] 228; 229 %a2 = getelementptr { i32, i32 }, ptr %a, i64 %idx 230 %a3 = getelementptr i8, ptr %a2, i64 4 231 ret ptr %a3 232} 233 234define ptr @geps_combinable_different_elem_type7(ptr %a, i64 %idx) { 235; CHECK-LABEL: @geps_combinable_different_elem_type7( 236; CHECK-NEXT: [[A2:%.*]] = getelementptr { i32, i32 }, ptr [[A:%.*]], i64 [[IDX:%.*]], i32 1 237; CHECK-NEXT: [[A3:%.*]] = getelementptr i8, ptr [[A2]], i64 4 238; CHECK-NEXT: ret ptr [[A3]] 239; 240 %a2 = getelementptr { i32, i32 }, ptr %a, i64 %idx, i32 1 241 %a3 = getelementptr i8, ptr %a2, i64 4 242 ret ptr %a3 243} 244 245define ptr @geps_combinable_different_elem_type8(ptr %a, i64 %idx) { 246; CHECK-LABEL: @geps_combinable_different_elem_type8( 247; CHECK-NEXT: [[A2:%.*]] = getelementptr inbounds { { i32, i32 } }, ptr [[A:%.*]], i64 [[IDX:%.*]], i32 0, i32 1 248; CHECK-NEXT: [[A3:%.*]] = getelementptr inbounds nuw i8, ptr [[A2]], i64 4 249; CHECK-NEXT: ret ptr [[A3]] 250; 251 %a2 = getelementptr inbounds { { i32, i32 } }, ptr %a, i64 %idx, i32 0, i32 1 252 %a3 = getelementptr inbounds i8, ptr %a2, i32 4 253 ret ptr %a3 254} 255 256define ptr @geps_combinable_different_elem_type9(ptr %a, i64 %idx) { 257; CHECK-LABEL: @geps_combinable_different_elem_type9( 258; CHECK-NEXT: [[A3:%.*]] = getelementptr inbounds { { i32, i32 } }, ptr [[A:%.*]], i64 [[IDX:%.*]] 259; CHECK-NEXT: ret ptr [[A3]] 260; 261 %a2 = getelementptr inbounds { { i32, i32 } }, ptr %a, i64 %idx, i32 0, i32 1 262 %a3 = getelementptr inbounds i8, ptr %a2, i32 -4 263 ret ptr %a3 264} 265 266declare void @use(ptr) 267 268define ptr @geps_combinable_different_elem_type_extra_use1(ptr %a) { 269; CHECK-LABEL: @geps_combinable_different_elem_type_extra_use1( 270; CHECK-NEXT: [[A2:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 4 271; CHECK-NEXT: call void @use(ptr [[A2]]) 272; CHECK-NEXT: [[A3:%.*]] = getelementptr i8, ptr [[A]], i64 8 273; CHECK-NEXT: ret ptr [[A3]] 274; 275 %a2 = getelementptr { i32, i32 }, ptr %a, i32 0, i32 1 276 call void @use(ptr %a2) 277 %a3 = getelementptr i8, ptr %a2, i64 4 278 ret ptr %a3 279} 280 281define ptr @geps_combinable_different_elem_type_extra_use2(ptr %a, i64 %idx) { 282; CHECK-LABEL: @geps_combinable_different_elem_type_extra_use2( 283; CHECK-NEXT: [[A2:%.*]] = getelementptr { i32, i32 }, ptr [[A:%.*]], i64 [[IDX:%.*]] 284; CHECK-NEXT: call void @use(ptr [[A2]]) 285; CHECK-NEXT: [[A3:%.*]] = getelementptr i8, ptr [[A2]], i64 4 286; CHECK-NEXT: ret ptr [[A3]] 287; 288 %a2 = getelementptr { i32, i32 }, ptr %a, i64 %idx 289 call void @use(ptr %a2) 290 %a3 = getelementptr i8, ptr %a2, i64 4 291 ret ptr %a3 292} 293 294define ptr @geps_combinable_scalable(ptr %a, i64 %idx) { 295; CHECK-LABEL: @geps_combinable_scalable( 296; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.vscale.i64() 297; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[TMP1]], 3 298; CHECK-NEXT: [[A2:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i64 [[TMP2]] 299; CHECK-NEXT: [[A3:%.*]] = getelementptr inbounds nuw i8, ptr [[A2]], i64 4 300; CHECK-NEXT: ret ptr [[A3]] 301; 302 %a2 = getelementptr inbounds <vscale x 2 x i32>, ptr %a, i64 1 303 %a3 = getelementptr inbounds i8, ptr %a2, i32 4 304 ret ptr %a3 305} 306 307define ptr @geps_combinable_scalable_vector_array(ptr %a, i64 %idx) { 308; CHECK-LABEL: @geps_combinable_scalable_vector_array( 309; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.vscale.i64() 310; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[TMP1]], 5 311; CHECK-NEXT: [[A2:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i64 [[TMP2]] 312; CHECK-NEXT: [[A3:%.*]] = getelementptr inbounds nuw i8, ptr [[A2]], i64 4 313; CHECK-NEXT: ret ptr [[A3]] 314; 315 %a2 = getelementptr inbounds [4 x <vscale x 2 x i32>], ptr %a, i64 1 316 %a3 = getelementptr inbounds i8, ptr %a2, i32 4 317 ret ptr %a3 318} 319 320define i1 @compare_geps_same_indices(ptr %a, ptr %b, i64 %idx) { 321; CHECK-LABEL: @compare_geps_same_indices( 322; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[A:%.*]], [[B:%.*]] 323; CHECK-NEXT: ret i1 [[C]] 324; 325 %a2 = getelementptr i32, ptr %a, i64 %idx 326 %b2 = getelementptr i32, ptr %b, i64 %idx 327 %c = icmp eq ptr %a2, %b2 328 ret i1 %c 329} 330 331define i1 @compare_geps_same_indices_different_types(ptr %a, ptr %b, i64 %idx) { 332; CHECK-LABEL: @compare_geps_same_indices_different_types( 333; CHECK-NEXT: [[A2:%.*]] = getelementptr i32, ptr [[A:%.*]], i64 [[IDX:%.*]] 334; CHECK-NEXT: [[B2:%.*]] = getelementptr i64, ptr [[B:%.*]], i64 [[IDX]] 335; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[A2]], [[B2]] 336; CHECK-NEXT: ret i1 [[C]] 337; 338 %a2 = getelementptr i32, ptr %a, i64 %idx 339 %b2 = getelementptr i64, ptr %b, i64 %idx 340 %c = icmp eq ptr %a2, %b2 341 ret i1 %c 342} 343 344define i1 @compare_gep_with_base(ptr %p, i64 %idx) { 345; CHECK-LABEL: @compare_gep_with_base( 346; CHECK-NEXT: [[C:%.*]] = icmp eq i64 [[IDX:%.*]], 0 347; CHECK-NEXT: ret i1 [[C]] 348; 349 %gep = getelementptr inbounds i32, ptr %p, i64 %idx 350 %c = icmp eq ptr %gep, %p 351 ret i1 %c 352} 353 354define <2 x i1> @compare_gep_with_base_vector1(<2 x ptr> %p, i64 %idx) { 355; CHECK-LABEL: @compare_gep_with_base_vector1( 356; CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[IDX:%.*]], i64 0 357; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i64> [[DOTSPLATINSERT]], <i64 2, i64 0> 358; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i64> [[TMP1]], zeroinitializer 359; CHECK-NEXT: [[C:%.*]] = shufflevector <2 x i1> [[TMP2]], <2 x i1> poison, <2 x i32> zeroinitializer 360; CHECK-NEXT: ret <2 x i1> [[C]] 361; 362 %gep = getelementptr inbounds i32, <2 x ptr> %p, i64 %idx 363 %c = icmp eq <2 x ptr> %gep, %p 364 ret <2 x i1> %c 365} 366 367define <2 x i1> @compare_gep_with_base_vector2(<2 x ptr> %p, <2 x i64> %idx) { 368; CHECK-LABEL: @compare_gep_with_base_vector2( 369; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i64> [[IDX:%.*]], zeroinitializer 370; CHECK-NEXT: ret <2 x i1> [[C]] 371; 372 %gep = getelementptr inbounds i32, <2 x ptr> %p, <2 x i64> %idx 373 %c = icmp eq <2 x ptr> %gep, %p 374 ret <2 x i1> %c 375} 376 377define <4 x i1> @compare_geps_same_indices_scalar_vector_base_mismatch(ptr %ptr, <4 x ptr> %ptrs) { 378; CHECK-LABEL: @compare_geps_same_indices_scalar_vector_base_mismatch( 379; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i16, <4 x ptr> [[PTRS:%.*]], <4 x i64> <i64 1, i64 2, i64 3, i64 4> 380; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i16, ptr [[PTR:%.*]], <4 x i64> <i64 1, i64 2, i64 3, i64 4> 381; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x ptr> [[GEP1]], [[GEP2]] 382; CHECK-NEXT: ret <4 x i1> [[CMP]] 383; 384 %gep1 = getelementptr i16, <4 x ptr> %ptrs, <4 x i64> <i64 1, i64 2, i64 3, i64 4> 385 %gep2 = getelementptr i16, ptr %ptr, <4 x i64> <i64 1, i64 2, i64 3, i64 4> 386 %cmp = icmp eq <4 x ptr> %gep1, %gep2 387 ret <4 x i1> %cmp 388} 389 390define ptr @indexed_compare(ptr %A, i64 %offset) { 391; CHECK-LABEL: @indexed_compare( 392; CHECK-NEXT: entry: 393; CHECK-NEXT: [[TMP_IDX:%.*]] = shl nsw i64 [[OFFSET:%.*]], 2 394; CHECK-NEXT: br label [[BB:%.*]] 395; CHECK: bb: 396; CHECK-NEXT: [[RHS_IDX:%.*]] = phi i64 [ [[RHS_ADD:%.*]], [[BB]] ], [ [[TMP_IDX]], [[ENTRY:%.*]] ] 397; CHECK-NEXT: [[RHS_ADD]] = add nsw i64 [[RHS_IDX]], 4 398; CHECK-NEXT: [[COND:%.*]] = icmp sgt i64 [[RHS_IDX]], 400 399; CHECK-NEXT: br i1 [[COND]], label [[BB2:%.*]], label [[BB]] 400; CHECK: bb2: 401; CHECK-NEXT: [[RHS_PTR:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i64 [[RHS_IDX]] 402; CHECK-NEXT: ret ptr [[RHS_PTR]] 403; 404entry: 405 %tmp = getelementptr inbounds i32, ptr %A, i64 %offset 406 br label %bb 407 408bb: 409 %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ] 410 %LHS = getelementptr inbounds i32, ptr %A, i32 100 411 %RHS.next = getelementptr inbounds i32, ptr %RHS, i64 1 412 %cond = icmp ult ptr %LHS, %RHS 413 br i1 %cond, label %bb2, label %bb 414 415bb2: 416 ret ptr %RHS 417} 418 419define ptr @indexed_compare_different_types(ptr %A, i64 %offset) { 420; CHECK-LABEL: @indexed_compare_different_types( 421; CHECK-NEXT: entry: 422; CHECK-NEXT: [[TMP_IDX:%.*]] = shl nsw i64 [[OFFSET:%.*]], 2 423; CHECK-NEXT: br label [[BB:%.*]] 424; CHECK: bb: 425; CHECK-NEXT: [[RHS_IDX:%.*]] = phi i64 [ [[RHS_ADD:%.*]], [[BB]] ], [ [[TMP_IDX]], [[ENTRY:%.*]] ] 426; CHECK-NEXT: [[RHS_ADD]] = add nsw i64 [[RHS_IDX]], 4 427; CHECK-NEXT: [[COND:%.*]] = icmp sgt i64 [[RHS_IDX]], 800 428; CHECK-NEXT: br i1 [[COND]], label [[BB2:%.*]], label [[BB]] 429; CHECK: bb2: 430; CHECK-NEXT: [[RHS_PTR:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i64 [[RHS_IDX]] 431; CHECK-NEXT: ret ptr [[RHS_PTR]] 432; 433entry: 434 %tmp = getelementptr inbounds i32, ptr %A, i64 %offset 435 br label %bb 436 437bb: 438 %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ] 439 %LHS = getelementptr inbounds i64, ptr %A, i32 100 440 %RHS.next = getelementptr inbounds i32, ptr %RHS, i64 1 441 %cond = icmp ult ptr %LHS, %RHS 442 br i1 %cond, label %bb2, label %bb 443 444bb2: 445 ret ptr %RHS 446} 447 448define ptr addrspace(1) @gep_of_addrspace_cast(ptr %ptr) { 449; CHECK-LABEL: @gep_of_addrspace_cast( 450; CHECK-NEXT: [[CAST1:%.*]] = addrspacecast ptr [[PTR:%.*]] to ptr addrspace(1) 451; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(1) [[CAST1]], i64 4 452; CHECK-NEXT: ret ptr addrspace(1) [[GEP]] 453; 454 %cast1 = addrspacecast ptr %ptr to ptr addrspace(1) 455 %gep = getelementptr inbounds i32, ptr addrspace(1) %cast1, i64 1 456 ret ptr addrspace(1) %gep 457} 458 459define i1 @cmp_gep_same_base_same_type(ptr %ptr, i64 %idx1, i64 %idx2) { 460; CHECK-LABEL: @cmp_gep_same_base_same_type( 461; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[IDX1:%.*]], [[IDX2:%.*]] 462; CHECK-NEXT: ret i1 [[CMP]] 463; 464 %gep1 = getelementptr inbounds i32, ptr %ptr, i64 %idx1 465 %gep2 = getelementptr inbounds i32, ptr %ptr, i64 %idx2 466 %cmp = icmp ult ptr %gep1, %gep2 467 ret i1 %cmp 468} 469 470define i1 @cmp_gep_same_base_different_type(ptr %ptr, i64 %idx1, i64 %idx2) { 471; CHECK-LABEL: @cmp_gep_same_base_different_type( 472; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[IDX1:%.*]], 2 473; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl nsw i64 [[IDX2:%.*]], 3 474; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[GEP1_IDX]], [[GEP2_IDX]] 475; CHECK-NEXT: ret i1 [[CMP]] 476; 477 %gep1 = getelementptr inbounds i32, ptr %ptr, i64 %idx1 478 %gep2 = getelementptr inbounds i64, ptr %ptr, i64 %idx2 479 %cmp = icmp ult ptr %gep1, %gep2 480 ret i1 %cmp 481} 482 483@ary = constant [4 x i8] [i8 1, i8 2, i8 3, i8 4] 484 485define i1 @cmp_load_gep_global(i64 %idx) { 486; CHECK-LABEL: @cmp_load_gep_global( 487; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IDX:%.*]], 2 488; CHECK-NEXT: ret i1 [[CMP]] 489; 490 %gep = getelementptr [4 x i8], ptr @ary, i64 0, i64 %idx 491 %load = load i8, ptr %gep 492 %cmp = icmp eq i8 %load, 3 493 ret i1 %cmp 494} 495 496define i1 @cmp_load_gep_global_different_load_type(i64 %idx) { 497; CHECK-LABEL: @cmp_load_gep_global_different_load_type( 498; CHECK-NEXT: [[GEP:%.*]] = getelementptr [4 x i8], ptr @ary, i64 0, i64 [[IDX:%.*]] 499; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[GEP]], align 2 500; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[LOAD]], 3 501; CHECK-NEXT: ret i1 [[CMP]] 502; 503 %gep = getelementptr [4 x i8], ptr @ary, i64 0, i64 %idx 504 %load = load i16, ptr %gep 505 %cmp = icmp eq i16 %load, 3 506 ret i1 %cmp 507} 508 509define i1 @cmp_load_gep_global_different_gep_type(i64 %idx) { 510; CHECK-LABEL: @cmp_load_gep_global_different_gep_type( 511; CHECK-NEXT: [[GEP:%.*]] = getelementptr [4 x i16], ptr @ary, i64 0, i64 [[IDX:%.*]] 512; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[GEP]], align 2 513; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[LOAD]], 3 514; CHECK-NEXT: ret i1 [[CMP]] 515; 516 %gep = getelementptr [4 x i16], ptr @ary, i64 0, i64 %idx 517 %load = load i16, ptr %gep 518 %cmp = icmp eq i16 %load, 3 519 ret i1 %cmp 520} 521 522define ptr @phi_of_gep(i1 %c, ptr %p) { 523; CHECK-LABEL: @phi_of_gep( 524; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]] 525; CHECK: if: 526; CHECK-NEXT: br label [[JOIN:%.*]] 527; CHECK: else: 528; CHECK-NEXT: br label [[JOIN]] 529; CHECK: join: 530; CHECK-NEXT: [[PHI:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 4 531; CHECK-NEXT: ret ptr [[PHI]] 532; 533 br i1 %c, label %if, label %else 534 535if: 536 %gep1 = getelementptr i32, ptr %p, i64 1 537 br label %join 538 539else: 540 %gep2 = getelementptr i32, ptr %p, i64 1 541 br label %join 542 543join: 544 %phi = phi ptr [ %gep1, %if ], [ %gep2, %else ] 545 ret ptr %phi 546} 547 548define ptr @phi_of_gep_flags_1(i1 %c, ptr %p) { 549; CHECK-LABEL: @phi_of_gep_flags_1( 550; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]] 551; CHECK: if: 552; CHECK-NEXT: br label [[JOIN:%.*]] 553; CHECK: else: 554; CHECK-NEXT: br label [[JOIN]] 555; CHECK: join: 556; CHECK-NEXT: [[PHI:%.*]] = getelementptr nusw nuw i8, ptr [[P:%.*]], i64 4 557; CHECK-NEXT: ret ptr [[PHI]] 558; 559 br i1 %c, label %if, label %else 560 561if: 562 %gep1 = getelementptr inbounds i32, ptr %p, i64 1 563 br label %join 564 565else: 566 %gep2 = getelementptr nusw nuw i32, ptr %p, i64 1 567 br label %join 568 569join: 570 %phi = phi ptr [ %gep1, %if ], [ %gep2, %else ] 571 ret ptr %phi 572} 573 574define ptr @phi_of_gep_flags_2(i1 %c, ptr %p) { 575; CHECK-LABEL: @phi_of_gep_flags_2( 576; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]] 577; CHECK: if: 578; CHECK-NEXT: br label [[JOIN:%.*]] 579; CHECK: else: 580; CHECK-NEXT: br label [[JOIN]] 581; CHECK: join: 582; CHECK-NEXT: [[PHI:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 4 583; CHECK-NEXT: ret ptr [[PHI]] 584; 585 br i1 %c, label %if, label %else 586 587if: 588 %gep1 = getelementptr nusw nuw i32, ptr %p, i64 1 589 br label %join 590 591else: 592 %gep2 = getelementptr nuw i32, ptr %p, i64 1 593 br label %join 594 595join: 596 %phi = phi ptr [ %gep1, %if ], [ %gep2, %else ] 597 ret ptr %phi 598} 599 600define ptr @phi_of_gep_different_type(i1 %c, ptr %p) { 601; CHECK-LABEL: @phi_of_gep_different_type( 602; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]] 603; CHECK: if: 604; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 4 605; CHECK-NEXT: br label [[JOIN:%.*]] 606; CHECK: else: 607; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, ptr [[P]], i64 8 608; CHECK-NEXT: br label [[JOIN]] 609; CHECK: join: 610; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[GEP1]], [[IF]] ], [ [[GEP2]], [[ELSE]] ] 611; CHECK-NEXT: ret ptr [[PHI]] 612; 613 br i1 %c, label %if, label %else 614 615if: 616 %gep1 = getelementptr i32, ptr %p, i64 1 617 br label %join 618 619else: 620 %gep2 = getelementptr i64, ptr %p, i64 1 621 br label %join 622 623join: 624 %phi = phi ptr [ %gep1, %if ], [ %gep2, %else ] 625 ret ptr %phi 626} 627 628define ptr @gep_of_phi_of_gep(i1 %c, ptr %p) { 629; CHECK-LABEL: @gep_of_phi_of_gep( 630; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]] 631; CHECK: if: 632; CHECK-NEXT: br label [[JOIN:%.*]] 633; CHECK: else: 634; CHECK-NEXT: br label [[JOIN]] 635; CHECK: join: 636; CHECK-NEXT: [[TMP1:%.*]] = phi i64 [ 4, [[IF]] ], [ 8, [[ELSE]] ] 637; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[TMP1]] 638; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[TMP2]], i64 4 639; CHECK-NEXT: ret ptr [[GEP]] 640; 641 br i1 %c, label %if, label %else 642 643if: 644 %gep1 = getelementptr i32, ptr %p, i64 1 645 br label %join 646 647else: 648 %gep2 = getelementptr i32, ptr %p, i64 2 649 br label %join 650 651join: 652 %phi = phi ptr [ %gep1, %if ], [ %gep2, %else ] 653 %gep = getelementptr i32, ptr %phi, i64 1 654 ret ptr %gep 655} 656 657define ptr @gep_of_phi_of_gep_flags1(i1 %c, ptr %p) { 658; CHECK-LABEL: @gep_of_phi_of_gep_flags1( 659; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]] 660; CHECK: if: 661; CHECK-NEXT: br label [[JOIN:%.*]] 662; CHECK: else: 663; CHECK-NEXT: br label [[JOIN]] 664; CHECK: join: 665; CHECK-NEXT: [[TMP1:%.*]] = phi i64 [ 4, [[IF]] ], [ 8, [[ELSE]] ] 666; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[TMP1]] 667; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[TMP2]], i64 4 668; CHECK-NEXT: ret ptr [[GEP]] 669; 670 br i1 %c, label %if, label %else 671 672if: 673 %gep1 = getelementptr inbounds i32, ptr %p, i64 1 674 br label %join 675 676else: 677 %gep2 = getelementptr i32, ptr %p, i64 2 678 br label %join 679 680join: 681 %phi = phi ptr [ %gep1, %if ], [ %gep2, %else ] 682 %gep = getelementptr i32, ptr %phi, i64 1 683 ret ptr %gep 684} 685 686define ptr @gep_of_phi_of_gep_flags2(i1 %c, ptr %p) { 687; CHECK-LABEL: @gep_of_phi_of_gep_flags2( 688; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]] 689; CHECK: if: 690; CHECK-NEXT: br label [[JOIN:%.*]] 691; CHECK: else: 692; CHECK-NEXT: br label [[JOIN]] 693; CHECK: join: 694; CHECK-NEXT: [[TMP1:%.*]] = phi i64 [ 4, [[IF]] ], [ 8, [[ELSE]] ] 695; CHECK-NEXT: [[TMP2:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 [[TMP1]] 696; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[TMP2]], i64 4 697; CHECK-NEXT: ret ptr [[GEP]] 698; 699 br i1 %c, label %if, label %else 700 701if: 702 %gep1 = getelementptr nuw i32, ptr %p, i64 1 703 br label %join 704 705else: 706 %gep2 = getelementptr nuw i32, ptr %p, i64 2 707 br label %join 708 709join: 710 %phi = phi ptr [ %gep1, %if ], [ %gep2, %else ] 711 %gep = getelementptr i32, ptr %phi, i64 1 712 ret ptr %gep 713} 714 715define ptr @gep_of_phi_of_gep_different_type(i1 %c, ptr %p) { 716; CHECK-LABEL: @gep_of_phi_of_gep_different_type( 717; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]] 718; CHECK: if: 719; CHECK-NEXT: br label [[JOIN:%.*]] 720; CHECK: else: 721; CHECK-NEXT: br label [[JOIN]] 722; CHECK: join: 723; CHECK-NEXT: [[TMP1:%.*]] = phi i64 [ 4, [[IF]] ], [ 16, [[ELSE]] ] 724; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[TMP1]] 725; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[TMP2]], i64 4 726; CHECK-NEXT: ret ptr [[GEP]] 727; 728 br i1 %c, label %if, label %else 729 730if: 731 %gep1 = getelementptr i32, ptr %p, i64 1 732 br label %join 733 734else: 735 %gep2 = getelementptr i64, ptr %p, i64 2 736 br label %join 737 738join: 739 %phi = phi ptr [ %gep1, %if ], [ %gep2, %else ] 740 %gep = getelementptr i32, ptr %phi, i64 1 741 ret ptr %gep 742} 743 744define ptr @select_of_gep(i1 %c, ptr %p) { 745; CHECK-LABEL: @select_of_gep( 746; CHECK-NEXT: [[S_V:%.*]] = select i1 [[C:%.*]], i64 4, i64 8 747; CHECK-NEXT: [[S:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[S_V]] 748; CHECK-NEXT: ret ptr [[S]] 749; 750 %gep1 = getelementptr i32, ptr %p, i64 1 751 %gep2 = getelementptr i32, ptr %p, i64 2 752 %s = select i1 %c, ptr %gep1, ptr %gep2 753 ret ptr %s 754} 755 756define ptr @select_of_gep_flags_1(i1 %c, ptr %p) { 757; CHECK-LABEL: @select_of_gep_flags_1( 758; CHECK-NEXT: [[S_V:%.*]] = select i1 [[C:%.*]], i64 4, i64 8 759; CHECK-NEXT: [[S:%.*]] = getelementptr nusw nuw i8, ptr [[P:%.*]], i64 [[S_V]] 760; CHECK-NEXT: ret ptr [[S]] 761; 762 %gep1 = getelementptr inbounds i32, ptr %p, i64 1 763 %gep2 = getelementptr nusw nuw i32, ptr %p, i64 2 764 %s = select i1 %c, ptr %gep1, ptr %gep2 765 ret ptr %s 766} 767 768define ptr @select_of_gep_flags_2(i1 %c, ptr %p) { 769; CHECK-LABEL: @select_of_gep_flags_2( 770; CHECK-NEXT: [[S_V:%.*]] = select i1 [[C:%.*]], i64 4, i64 8 771; CHECK-NEXT: [[S:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 [[S_V]] 772; CHECK-NEXT: ret ptr [[S]] 773; 774 %gep1 = getelementptr nuw i32, ptr %p, i64 1 775 %gep2 = getelementptr nusw nuw i32, ptr %p, i64 2 776 %s = select i1 %c, ptr %gep1, ptr %gep2 777 ret ptr %s 778} 779 780define ptr @select_of_gep_different_type(i1 %c, ptr %p) { 781; CHECK-LABEL: @select_of_gep_different_type( 782; CHECK-NEXT: [[S_V:%.*]] = select i1 [[C:%.*]], i64 4, i64 16 783; CHECK-NEXT: [[S:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[S_V]] 784; CHECK-NEXT: ret ptr [[S]] 785; 786 %gep1 = getelementptr i32, ptr %p, i64 1 787 %gep2 = getelementptr i64, ptr %p, i64 2 788 %s = select i1 %c, ptr %gep1, ptr %gep2 789 ret ptr %s 790} 791 792define void @dse(ptr %p) { 793; CHECK-LABEL: @dse( 794; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4 795; CHECK-NEXT: store i8 1, ptr [[P]], align 1 796; CHECK-NEXT: ret void 797; 798 store i32 0, ptr %p 799 store i8 1, ptr %p 800 ret void 801} 802 803declare void @call_i64(i64) 804declare void @call_byval(i64, ptr byval(i64)) 805 806define void @call_cast_ptr_to_int(ptr %p) { 807; CHECK-LABEL: @call_cast_ptr_to_int( 808; CHECK-NEXT: call void @call_i64(ptr [[P:%.*]]) 809; CHECK-NEXT: ret void 810; 811 call void @call_i64(ptr %p) 812 ret void 813} 814 815define void @call_cast_byval(ptr %p, ptr %p2) { 816; CHECK-LABEL: @call_cast_byval( 817; CHECK-NEXT: call void @call_byval(ptr [[P:%.*]], ptr byval(double) [[P2:%.*]]) 818; CHECK-NEXT: ret void 819; 820 call void @call_byval(ptr %p, ptr byval(double) %p2) 821 ret void 822} 823 824declare float @fmodf(float, float) 825 826define i32 @const_fold_call_with_func_type_mismatch() { 827; CHECK-LABEL: @const_fold_call_with_func_type_mismatch( 828; CHECK-NEXT: [[V:%.*]] = call i32 @fmodf(float 0x40091EB860000000, float 2.000000e+00) 829; CHECK-NEXT: ret i32 [[V]] 830; 831 %v = call i32 @fmodf(float 0x40091EB860000000, float 2.000000e+00) 832 ret i32 %v 833} 834