; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -passes=instcombine < %s | FileCheck %s
define ptr @bitcast_opaque_to_opaque(ptr %a) {
; CHECK-LABEL: @bitcast_opaque_to_opaque(
; CHECK-NEXT: ret ptr [[A:%.*]]
;
ret ptr %a
}
define ptr @bitcast_typed_to_opaque(ptr %a) {
; CHECK-LABEL: @bitcast_typed_to_opaque(
; CHECK-NEXT: ret ptr [[A:%.*]]
;
ret ptr %a
}
define ptr @bitcast_opaque_to_typed(ptr %a) {
; CHECK-LABEL: @bitcast_opaque_to_typed(
; CHECK-NEXT: ret ptr [[A:%.*]]
;
ret ptr %a
}
@g = global i8 0
define ptr @bitcast_typed_to_opaque_constexpr() {
; CHECK-LABEL: @bitcast_typed_to_opaque_constexpr(
; CHECK-NEXT: ret ptr @g
;
ret ptr @g
}
define ptr @addrspacecast_opaque_to_opaque(ptr addrspace(1) %a) {
; CHECK-LABEL: @addrspacecast_opaque_to_opaque(
; CHECK-NEXT: [[B:%.*]] = addrspacecast ptr addrspace(1) [[A:%.*]] to ptr
; CHECK-NEXT: ret ptr [[B]]
;
%b = addrspacecast ptr addrspace(1) %a to ptr
ret ptr %b
}
define ptr @addrspacecast_typed_to_opaque(ptr addrspace(1) %a) {
; CHECK-LABEL: @addrspacecast_typed_to_opaque(
; CHECK-NEXT: [[B:%.*]] = addrspacecast ptr addrspace(1) [[A:%.*]] to ptr
; CHECK-NEXT: ret ptr [[B]]
;
%b = addrspacecast ptr addrspace(1) %a to ptr
ret ptr %b
}
define ptr @addrspacecast_opaque_to_typed(ptr addrspace(1) %a) {
; CHECK-LABEL: @addrspacecast_opaque_to_typed(
; CHECK-NEXT: [[B:%.*]] = addrspacecast ptr addrspace(1) [[A:%.*]] to ptr
; CHECK-NEXT: ret ptr [[B]]
;
%b = addrspacecast ptr addrspace(1) %a to ptr
ret ptr %b
}
define ptr addrspace(1) @bitcast_and_addrspacecast_eliminable(ptr %a) {
; CHECK-LABEL: @bitcast_and_addrspacecast_eliminable(
; CHECK-NEXT: [[C:%.*]] = addrspacecast ptr [[A:%.*]] to ptr addrspace(1)
; CHECK-NEXT: ret ptr addrspace(1) [[C]]
;
%c = addrspacecast ptr %a to ptr addrspace(1)
ret ptr addrspace(1) %c
}
define ptr addrspace(1) @addrspacecast_typed_to_opaque_constexpr() {
; CHECK-LABEL: @addrspacecast_typed_to_opaque_constexpr(
; CHECK-NEXT: ret ptr addrspace(1) addrspacecast (ptr @g to ptr addrspace(1))
;
ret ptr addrspace(1) addrspacecast (ptr @g to ptr addrspace(1))
}
define ptr @gep_constexpr_1(ptr %a) {
; CHECK-LABEL: @gep_constexpr_1(
; CHECK-NEXT: ret ptr inttoptr (i64 6 to ptr)
;
ret ptr getelementptr (i16, ptr null, i32 3)
}
define ptr @gep_constexpr_2(ptr %a) {
; CHECK-LABEL: @gep_constexpr_2(
; CHECK-NEXT: ret ptr getelementptr (i8, ptr @g, i64 3)
;
ret ptr getelementptr (i8, ptr @g, i32 3)
}
define ptr addrspace(1) @gep_constexpr_3(ptr %a) {
; CHECK-LABEL: @gep_constexpr_3(
; CHECK-NEXT: ret ptr addrspace(1) getelementptr (i8, ptr addrspace(1) addrspacecast (ptr @g to ptr addrspace(1)), i64 3)
;
ret ptr addrspace(1) getelementptr ([0 x i8], ptr addrspace(1) addrspacecast (ptr @g to ptr addrspace(1)), i64 0, i32 3)
}
define ptr @load_bitcast_1(ptr %a) {
; CHECK-LABEL: @load_bitcast_1(
; CHECK-NEXT: [[B:%.*]] = load ptr, ptr [[A:%.*]], align 8
; CHECK-NEXT: ret ptr [[B]]
;
%b = load ptr, ptr %a
ret ptr %b
}
define ptr @load_bitcast_2(ptr %a) {
; CHECK-LABEL: @load_bitcast_2(
; CHECK-NEXT: [[C:%.*]] = load ptr, ptr [[A:%.*]], align 8
; CHECK-NEXT: ret ptr [[C]]
;
%c = load ptr, ptr %a
ret ptr %c
}
define void @call(ptr %a) {
; CHECK-LABEL: @call(
; CHECK-NEXT: call void [[A:%.*]]()
; CHECK-NEXT: ret void
;
call void %a()
ret void
}
declare void @varargs(...)
define void @varargs_cast_typed_to_opaque_same_type(ptr %a) {
; CHECK-LABEL: @varargs_cast_typed_to_opaque_same_type(
; CHECK-NEXT: call void (...) @varargs(ptr byval(i32) [[A:%.*]])
; CHECK-NEXT: ret void
;
call void (...) @varargs(ptr byval(i32) %a)
ret void
}
define void @varargs_cast_typed_to_opaque_different_type(ptr %a) {
; CHECK-LABEL: @varargs_cast_typed_to_opaque_different_type(
; CHECK-NEXT: call void (...) @varargs(ptr byval(float) [[A:%.*]])
; CHECK-NEXT: ret void
;
call void (...) @varargs(ptr byval(float) %a)
ret void
}
define void @varargs_cast_typed_to_opaque_different_size(ptr %a) {
; CHECK-LABEL: @varargs_cast_typed_to_opaque_different_size(
; CHECK-NEXT: call void (...) @varargs(ptr byval(i64) [[A:%.*]])
; CHECK-NEXT: ret void
;
call void (...) @varargs(ptr byval(i64) %a)
ret void
}
define void @varargs_cast_opaque_to_typed(ptr %a) {
; CHECK-LABEL: @varargs_cast_opaque_to_typed(
; CHECK-NEXT: call void (...) @varargs(ptr byval(i8) [[A:%.*]])
; CHECK-NEXT: ret void
;
call void (...) @varargs(ptr byval(i8) %a)
ret void
}
define ptr @geps_combinable(ptr %a) {
; CHECK-LABEL: @geps_combinable(
; CHECK-NEXT: [[A3:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 8
; CHECK-NEXT: ret ptr [[A3]]
;
%a2 = getelementptr { i32, { i32, i32 } }, ptr %a, i32 0, i32 1
%a3 = getelementptr { i32, i32 }, ptr %a2, i32 0, i32 1
ret ptr %a3
}
define ptr @geps_combinable_different_elem_type1(ptr %a) {
; CHECK-LABEL: @geps_combinable_different_elem_type1(
; CHECK-NEXT: [[A3:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 8
; CHECK-NEXT: ret ptr [[A3]]
;
%a2 = getelementptr { i32, i32 }, ptr %a, i32 0, i32 1
%a3 = getelementptr { i32, i32 }, ptr %a2, i32 0, i32 1
ret ptr %a3
}
define ptr @geps_combinable_different_elem_type2(ptr %a) {
; CHECK-LABEL: @geps_combinable_different_elem_type2(
; CHECK-NEXT: [[A3:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 8
; CHECK-NEXT: ret ptr [[A3]]
;
%a2 = getelementptr { i32, i32 }, ptr %a, i32 0, i32 1
%a3 = getelementptr i8, ptr %a2, i64 4
ret ptr %a3
}
define ptr @geps_combinable_different_elem_type3(ptr %a) {
; CHECK-LABEL: @geps_combinable_different_elem_type3(
; CHECK-NEXT: [[A3:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 12
; CHECK-NEXT: ret ptr [[A3]]
;
%a2 = getelementptr { i32, i32 }, ptr %a, i32 0, i32 1
%a3 = getelementptr i8, ptr %a2, i64 8
ret ptr %a3
}
define ptr @geps_combinable_different_elem_type4(ptr %a) {
; CHECK-LABEL: @geps_combinable_different_elem_type4(
; CHECK-NEXT: [[A3:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 14
; CHECK-NEXT: ret ptr [[A3]]
;
%a2 = getelementptr { i32, i32 }, ptr %a, i32 0, i32 1
%a3 = getelementptr i8, ptr %a2, i64 10
ret ptr %a3
}
define ptr @geps_combinable_different_elem_type5(ptr %a) {
; CHECK-LABEL: @geps_combinable_different_elem_type5(
; CHECK-NEXT: ret ptr [[A:%.*]]
;
%a2 = getelementptr { i32, i32 }, ptr %a, i32 0, i32 1
%a3 = getelementptr i8, ptr %a2, i64 -4
ret ptr %a3
}
define ptr @geps_combinable_different_elem_type6(ptr %a, i64 %idx) {
; CHECK-LABEL: @geps_combinable_different_elem_type6(
; CHECK-NEXT: [[A3:%.*]] = getelementptr { i32, i32 }, ptr [[A:%.*]], i64 [[IDX:%.*]], i32 1
; CHECK-NEXT: ret ptr [[A3]]
;
%a2 = getelementptr { i32, i32 }, ptr %a, i64 %idx
%a3 = getelementptr i8, ptr %a2, i64 4
ret ptr %a3
}
define ptr @geps_combinable_different_elem_type7(ptr %a, i64 %idx) {
; CHECK-LABEL: @geps_combinable_different_elem_type7(
; CHECK-NEXT: [[A2:%.*]] = getelementptr { i32, i32 }, ptr [[A:%.*]], i64 [[IDX:%.*]], i32 1
; CHECK-NEXT: [[A3:%.*]] = getelementptr i8, ptr [[A2]], i64 4
; CHECK-NEXT: ret ptr [[A3]]
;
%a2 = getelementptr { i32, i32 }, ptr %a, i64 %idx, i32 1
%a3 = getelementptr i8, ptr %a2, i64 4
ret ptr %a3
}
define ptr @geps_combinable_different_elem_type8(ptr %a, i64 %idx) {
; CHECK-LABEL: @geps_combinable_different_elem_type8(
; CHECK-NEXT: [[A2:%.*]] = getelementptr inbounds { { i32, i32 } }, ptr [[A:%.*]], i64 [[IDX:%.*]], i32 0, i32 1
; CHECK-NEXT: [[A3:%.*]] = getelementptr inbounds i8, ptr [[A2]], i64 4
; CHECK-NEXT: ret ptr [[A3]]
;
%a2 = getelementptr inbounds { { i32, i32 } }, ptr %a, i64 %idx, i32 0, i32 1
%a3 = getelementptr inbounds i8, ptr %a2, i32 4
ret ptr %a3
}
define ptr @geps_combinable_different_elem_type9(ptr %a, i64 %idx) {
; CHECK-LABEL: @geps_combinable_different_elem_type9(
; CHECK-NEXT: [[A3:%.*]] = getelementptr inbounds { { i32, i32 } }, ptr [[A:%.*]], i64 [[IDX:%.*]]
; CHECK-NEXT: ret ptr [[A3]]
;
%a2 = getelementptr inbounds { { i32, i32 } }, ptr %a, i64 %idx, i32 0, i32 1
%a3 = getelementptr inbounds i8, ptr %a2, i32 -4
ret ptr %a3
}
declare void @use(ptr)
define ptr @geps_combinable_different_elem_type_extra_use1(ptr %a) {
; CHECK-LABEL: @geps_combinable_different_elem_type_extra_use1(
; CHECK-NEXT: [[A2:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 4
; CHECK-NEXT: call void @use(ptr [[A2]])
; CHECK-NEXT: [[A3:%.*]] = getelementptr i8, ptr [[A]], i64 8
; CHECK-NEXT: ret ptr [[A3]]
;
%a2 = getelementptr { i32, i32 }, ptr %a, i32 0, i32 1
call void @use(ptr %a2)
%a3 = getelementptr i8, ptr %a2, i64 4
ret ptr %a3
}
define ptr @geps_combinable_different_elem_type_extra_use2(ptr %a, i64 %idx) {
; CHECK-LABEL: @geps_combinable_different_elem_type_extra_use2(
; CHECK-NEXT: [[A2:%.*]] = getelementptr { i32, i32 }, ptr [[A:%.*]], i64 [[IDX:%.*]]
; CHECK-NEXT: call void @use(ptr [[A2]])
; CHECK-NEXT: [[A3:%.*]] = getelementptr i8, ptr [[A2]], i64 4
; CHECK-NEXT: ret ptr [[A3]]
;
%a2 = getelementptr { i32, i32 }, ptr %a, i64 %idx
call void @use(ptr %a2)
%a3 = getelementptr i8, ptr %a2, i64 4
ret ptr %a3
}
define ptr @geps_combinable_scalable(ptr %a, i64 %idx) {
; CHECK-LABEL: @geps_combinable_scalable(
; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.vscale.i64()
; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[TMP1]], 3
; CHECK-NEXT: [[A2:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i64 [[TMP2]]
; CHECK-NEXT: [[A3:%.*]] = getelementptr inbounds i8, ptr [[A2]], i64 4
; CHECK-NEXT: ret ptr [[A3]]
;
%a2 = getelementptr inbounds <vscale x 2 x i32>, ptr %a, i64 1
%a3 = getelementptr inbounds i8, ptr %a2, i32 4
ret ptr %a3
}
define ptr @geps_combinable_scalable_vector_array(ptr %a, i64 %idx) {
; CHECK-LABEL: @geps_combinable_scalable_vector_array(
; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.vscale.i64()
; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[TMP1]], 5
; CHECK-NEXT: [[A2:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i64 [[TMP2]]
; CHECK-NEXT: [[A3:%.*]] = getelementptr inbounds i8, ptr [[A2]], i64 4
; CHECK-NEXT: ret ptr [[A3]]
;
%a2 = getelementptr inbounds [4 x <vscale x 2 x i32>], ptr %a, i64 1
%a3 = getelementptr inbounds i8, ptr %a2, i32 4
ret ptr %a3
}
define i1 @compare_geps_same_indices(ptr %a, ptr %b, i64 %idx) {
; CHECK-LABEL: @compare_geps_same_indices(
; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: ret i1 [[C]]
;
%a2 = getelementptr i32, ptr %a, i64 %idx
%b2 = getelementptr i32, ptr %b, i64 %idx
%c = icmp eq ptr %a2, %b2
ret i1 %c
}
define i1 @compare_geps_same_indices_different_types(ptr %a, ptr %b, i64 %idx) {
; CHECK-LABEL: @compare_geps_same_indices_different_types(
; CHECK-NEXT: [[A2:%.*]] = getelementptr i32, ptr [[A:%.*]], i64 [[IDX:%.*]]
; CHECK-NEXT: [[B2:%.*]] = getelementptr i64, ptr [[B:%.*]], i64 [[IDX]]
; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[A2]], [[B2]]
; CHECK-NEXT: ret i1 [[C]]
;
%a2 = getelementptr i32, ptr %a, i64 %idx
%b2 = getelementptr i64, ptr %b, i64 %idx
%c = icmp eq ptr %a2, %b2
ret i1 %c
}
define i1 @compare_gep_with_base(ptr %p, i64 %idx) {
; CHECK-LABEL: @compare_gep_with_base(
; CHECK-NEXT: [[C:%.*]] = icmp eq i64 [[IDX:%.*]], 0
; CHECK-NEXT: ret i1 [[C]]
;
%gep = getelementptr inbounds i32, ptr %p, i64 %idx
%c = icmp eq ptr %gep, %p
ret i1 %c
}
define <2 x i1> @compare_gep_with_base_vector1(<2 x ptr> %p, i64 %idx) {
; CHECK-LABEL: @compare_gep_with_base_vector1(
; CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[IDX:%.*]], i64 0
; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i64> [[DOTSPLATINSERT]], <i64 2, i64 0>
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i64> [[TMP1]], zeroinitializer
; CHECK-NEXT: [[C:%.*]] = shufflevector <2 x i1> [[TMP2]], <2 x i1> poison, <2 x i32> zeroinitializer
; CHECK-NEXT: ret <2 x i1> [[C]]
;
%gep = getelementptr inbounds i32, <2 x ptr> %p, i64 %idx
%c = icmp eq <2 x ptr> %gep, %p
ret <2 x i1> %c
}
define <2 x i1> @compare_gep_with_base_vector2(<2 x ptr> %p, <2 x i64> %idx) {
; CHECK-LABEL: @compare_gep_with_base_vector2(
; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i64> [[IDX:%.*]], zeroinitializer
; CHECK-NEXT: ret <2 x i1> [[C]]
;
%gep = getelementptr inbounds i32, <2 x ptr> %p, <2 x i64> %idx
%c = icmp eq <2 x ptr> %gep, %p
ret <2 x i1> %c
}
define <4 x i1> @compare_geps_same_indices_scalar_vector_base_mismatch(ptr %ptr, <4 x ptr> %ptrs) {
; CHECK-LABEL: @compare_geps_same_indices_scalar_vector_base_mismatch(
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i16, <4 x ptr> [[PTRS:%.*]], <4 x i64> <i64 1, i64 2, i64 3, i64 4>
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i16, ptr [[PTR:%.*]], <4 x i64> <i64 1, i64 2, i64 3, i64 4>
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x ptr> [[GEP1]], [[GEP2]]
; CHECK-NEXT: ret <4 x i1> [[CMP]]
;
%gep1 = getelementptr i16, <4 x ptr> %ptrs, <4 x i64> <i64 1, i64 2, i64 3, i64 4>
%gep2 = getelementptr i16, ptr %ptr, <4 x i64> <i64 1, i64 2, i64 3, i64 4>
%cmp = icmp eq <4 x ptr> %gep1, %gep2
ret <4 x i1> %cmp
}
define ptr @indexed_compare(ptr %A, i64 %offset) {
; CHECK-LABEL: @indexed_compare(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP_IDX:%.*]] = shl nsw i64 [[OFFSET:%.*]], 2
; CHECK-NEXT: br label [[BB:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[RHS_IDX:%.*]] = phi i64 [ [[RHS_ADD:%.*]], [[BB]] ], [ [[TMP_IDX]], [[ENTRY:%.*]] ]
; CHECK-NEXT: [[RHS_ADD]] = add nsw i64 [[RHS_IDX]], 4
; CHECK-NEXT: [[COND:%.*]] = icmp sgt i64 [[RHS_IDX]], 400
; CHECK-NEXT: br i1 [[COND]], label [[BB2:%.*]], label [[BB]]
; CHECK: bb2:
; CHECK-NEXT: [[RHS_PTR:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i64 [[RHS_IDX]]
; CHECK-NEXT: ret ptr [[RHS_PTR]]
;
entry:
%tmp = getelementptr inbounds i32, ptr %A, i64 %offset
br label %bb
bb:
%RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ]
%LHS = getelementptr inbounds i32, ptr %A, i32 100
%RHS.next = getelementptr inbounds i32, ptr %RHS, i64 1
%cond = icmp ult ptr %LHS, %RHS
br i1 %cond, label %bb2, label %bb
bb2:
ret ptr %RHS
}
define ptr @indexed_compare_different_types(ptr %A, i64 %offset) {
; CHECK-LABEL: @indexed_compare_different_types(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP_IDX:%.*]] = shl nsw i64 [[OFFSET:%.*]], 2
; CHECK-NEXT: br label [[BB:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[RHS_IDX:%.*]] = phi i64 [ [[RHS_ADD:%.*]], [[BB]] ], [ [[TMP_IDX]], [[ENTRY:%.*]] ]
; CHECK-NEXT: [[RHS_ADD]] = add nsw i64 [[RHS_IDX]], 4
; CHECK-NEXT: [[COND:%.*]] = icmp sgt i64 [[RHS_IDX]], 800
; CHECK-NEXT: br i1 [[COND]], label [[BB2:%.*]], label [[BB]]
; CHECK: bb2:
; CHECK-NEXT: [[RHS_PTR:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i64 [[RHS_IDX]]
; CHECK-NEXT: ret ptr [[RHS_PTR]]
;
entry:
%tmp = getelementptr inbounds i32, ptr %A, i64 %offset
br label %bb
bb:
%RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ]
%LHS = getelementptr inbounds i64, ptr %A, i32 100
%RHS.next = getelementptr inbounds i32, ptr %RHS, i64 1
%cond = icmp ult ptr %LHS, %RHS
br i1 %cond, label %bb2, label %bb
bb2:
ret ptr %RHS
}
define ptr addrspace(1) @gep_of_addrspace_cast(ptr %ptr) {
; CHECK-LABEL: @gep_of_addrspace_cast(
; CHECK-NEXT: [[CAST1:%.*]] = addrspacecast ptr [[PTR:%.*]] to ptr addrspace(1)
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr addrspace(1) [[CAST1]], i64 4
; CHECK-NEXT: ret ptr addrspace(1) [[GEP]]
;
%cast1 = addrspacecast ptr %ptr to ptr addrspace(1)
%gep = getelementptr inbounds i32, ptr addrspace(1) %cast1, i64 1
ret ptr addrspace(1) %gep
}
define i1 @cmp_gep_same_base_same_type(ptr %ptr, i64 %idx1, i64 %idx2) {
; CHECK-LABEL: @cmp_gep_same_base_same_type(
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[IDX1:%.*]], [[IDX2:%.*]]
; CHECK-NEXT: ret i1 [[CMP]]
;
%gep1 = getelementptr inbounds i32, ptr %ptr, i64 %idx1
%gep2 = getelementptr inbounds i32, ptr %ptr, i64 %idx2
%cmp = icmp ult ptr %gep1, %gep2
ret i1 %cmp
}
define i1 @cmp_gep_same_base_different_type(ptr %ptr, i64 %idx1, i64 %idx2) {
; CHECK-LABEL: @cmp_gep_same_base_different_type(
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[IDX1:%.*]], 2
; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl nsw i64 [[IDX2:%.*]], 3
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[GEP1_IDX]], [[GEP2_IDX]]
; CHECK-NEXT: ret i1 [[CMP]]
;
%gep1 = getelementptr inbounds i32, ptr %ptr, i64 %idx1
%gep2 = getelementptr inbounds i64, ptr %ptr, i64 %idx2
%cmp = icmp ult ptr %gep1, %gep2
ret i1 %cmp
}
@ary = constant [4 x i8] [i8 1, i8 2, i8 3, i8 4]
define i1 @cmp_load_gep_global(i64 %idx) {
; CHECK-LABEL: @cmp_load_gep_global(
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IDX:%.*]], 2
; CHECK-NEXT: ret i1 [[CMP]]
;
%gep = getelementptr [4 x i8], ptr @ary, i64 0, i64 %idx
%load = load i8, ptr %gep
%cmp = icmp eq i8 %load, 3
ret i1 %cmp
}
define i1 @cmp_load_gep_global_different_load_type(i64 %idx) {
; CHECK-LABEL: @cmp_load_gep_global_different_load_type(
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [4 x i8], ptr @ary, i64 0, i64 [[IDX:%.*]]
; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[GEP]], align 2
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[LOAD]], 3
; CHECK-NEXT: ret i1 [[CMP]]
;
%gep = getelementptr [4 x i8], ptr @ary, i64 0, i64 %idx
%load = load i16, ptr %gep
%cmp = icmp eq i16 %load, 3
ret i1 %cmp
}
define i1 @cmp_load_gep_global_different_gep_type(i64 %idx) {
; CHECK-LABEL: @cmp_load_gep_global_different_gep_type(
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [4 x i16], ptr @ary, i64 0, i64 [[IDX:%.*]]
; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[GEP]], align 2
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[LOAD]], 3
; CHECK-NEXT: ret i1 [[CMP]]
;
%gep = getelementptr [4 x i16], ptr @ary, i64 0, i64 %idx
%load = load i16, ptr %gep
%cmp = icmp eq i16 %load, 3
ret i1 %cmp
}
define ptr @phi_of_gep(i1 %c, ptr %p) {
; CHECK-LABEL: @phi_of_gep(
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
; CHECK: if:
; CHECK-NEXT: br label [[JOIN:%.*]]
; CHECK: else:
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[PHI:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 4
; CHECK-NEXT: ret ptr [[PHI]]
;
br i1 %c, label %if, label %else
if:
%gep1 = getelementptr i32, ptr %p, i64 1
br label %join
else:
%gep2 = getelementptr i32, ptr %p, i64 1
br label %join
join:
%phi = phi ptr [ %gep1, %if ], [ %gep2, %else ]
ret ptr %phi
}
define ptr @phi_of_gep_flags_1(i1 %c, ptr %p) {
; CHECK-LABEL: @phi_of_gep_flags_1(
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
; CHECK: if:
; CHECK-NEXT: br label [[JOIN:%.*]]
; CHECK: else:
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[PHI:%.*]] = getelementptr nusw nuw i8, ptr [[P:%.*]], i64 4
; CHECK-NEXT: ret ptr [[PHI]]
;
br i1 %c, label %if, label %else
if:
%gep1 = getelementptr inbounds i32, ptr %p, i64 1
br label %join
else:
%gep2 = getelementptr nusw nuw i32, ptr %p, i64 1
br label %join
join:
%phi = phi ptr [ %gep1, %if ], [ %gep2, %else ]
ret ptr %phi
}
define ptr @phi_of_gep_flags_2(i1 %c, ptr %p) {
; CHECK-LABEL: @phi_of_gep_flags_2(
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
; CHECK: if:
; CHECK-NEXT: br label [[JOIN:%.*]]
; CHECK: else:
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[PHI:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 4
; CHECK-NEXT: ret ptr [[PHI]]
;
br i1 %c, label %if, label %else
if:
%gep1 = getelementptr nusw nuw i32, ptr %p, i64 1
br label %join
else:
%gep2 = getelementptr nuw i32, ptr %p, i64 1
br label %join
join:
%phi = phi ptr [ %gep1, %if ], [ %gep2, %else ]
ret ptr %phi
}
define ptr @phi_of_gep_different_type(i1 %c, ptr %p) {
; CHECK-LABEL: @phi_of_gep_different_type(
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
; CHECK: if:
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 4
; CHECK-NEXT: br label [[JOIN:%.*]]
; CHECK: else:
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, ptr [[P]], i64 8
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[GEP1]], [[IF]] ], [ [[GEP2]], [[ELSE]] ]
; CHECK-NEXT: ret ptr [[PHI]]
;
br i1 %c, label %if, label %else
if:
%gep1 = getelementptr i32, ptr %p, i64 1
br label %join
else:
%gep2 = getelementptr i64, ptr %p, i64 1
br label %join
join:
%phi = phi ptr [ %gep1, %if ], [ %gep2, %else ]
ret ptr %phi
}
define ptr @gep_of_phi_of_gep(i1 %c, ptr %p) {
; CHECK-LABEL: @gep_of_phi_of_gep(
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
; CHECK: if:
; CHECK-NEXT: br label [[JOIN:%.*]]
; CHECK: else:
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[TMP1:%.*]] = phi i64 [ 4, [[IF]] ], [ 8, [[ELSE]] ]
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[TMP1]]
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[TMP2]], i64 4
; CHECK-NEXT: ret ptr [[GEP]]
;
br i1 %c, label %if, label %else
if:
%gep1 = getelementptr i32, ptr %p, i64 1
br label %join
else:
%gep2 = getelementptr i32, ptr %p, i64 2
br label %join
join:
%phi = phi ptr [ %gep1, %if ], [ %gep2, %else ]
%gep = getelementptr i32, ptr %phi, i64 1
ret ptr %gep
}
define ptr @gep_of_phi_of_gep_different_type(i1 %c, ptr %p) {
; CHECK-LABEL: @gep_of_phi_of_gep_different_type(
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
; CHECK: if:
; CHECK-NEXT: br label [[JOIN:%.*]]
; CHECK: else:
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[TMP1:%.*]] = phi i64 [ 4, [[IF]] ], [ 16, [[ELSE]] ]
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[TMP1]]
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[TMP2]], i64 4
; CHECK-NEXT: ret ptr [[GEP]]
;
br i1 %c, label %if, label %else
if:
%gep1 = getelementptr i32, ptr %p, i64 1
br label %join
else:
%gep2 = getelementptr i64, ptr %p, i64 2
br label %join
join:
%phi = phi ptr [ %gep1, %if ], [ %gep2, %else ]
%gep = getelementptr i32, ptr %phi, i64 1
ret ptr %gep
}
define ptr @select_of_gep(i1 %c, ptr %p) {
; CHECK-LABEL: @select_of_gep(
; CHECK-NEXT: [[S_V:%.*]] = select i1 [[C:%.*]], i64 4, i64 8
; CHECK-NEXT: [[S:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[S_V]]
; CHECK-NEXT: ret ptr [[S]]
;
%gep1 = getelementptr i32, ptr %p, i64 1
%gep2 = getelementptr i32, ptr %p, i64 2
%s = select i1 %c, ptr %gep1, ptr %gep2
ret ptr %s
}
define ptr @select_of_gep_flags_1(i1 %c, ptr %p) {
; CHECK-LABEL: @select_of_gep_flags_1(
; CHECK-NEXT: [[S_V:%.*]] = select i1 [[C:%.*]], i64 4, i64 8
; CHECK-NEXT: [[S:%.*]] = getelementptr nusw i8, ptr [[P:%.*]], i64 [[S_V]]
; CHECK-NEXT: ret ptr [[S]]
;
%gep1 = getelementptr inbounds i32, ptr %p, i64 1
%gep2 = getelementptr nusw nuw i32, ptr %p, i64 2
%s = select i1 %c, ptr %gep1, ptr %gep2
ret ptr %s
}
define ptr @select_of_gep_flags_2(i1 %c, ptr %p) {
; CHECK-LABEL: @select_of_gep_flags_2(
; CHECK-NEXT: [[S_V:%.*]] = select i1 [[C:%.*]], i64 4, i64 8
; CHECK-NEXT: [[S:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 [[S_V]]
; CHECK-NEXT: ret ptr [[S]]
;
%gep1 = getelementptr nuw i32, ptr %p, i64 1
%gep2 = getelementptr nusw nuw i32, ptr %p, i64 2
%s = select i1 %c, ptr %gep1, ptr %gep2
ret ptr %s
}
define ptr @select_of_gep_different_type(i1 %c, ptr %p) {
; CHECK-LABEL: @select_of_gep_different_type(
; CHECK-NEXT: [[S_V:%.*]] = select i1 [[C:%.*]], i64 4, i64 16
; CHECK-NEXT: [[S:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[S_V]]
; CHECK-NEXT: ret ptr [[S]]
;
%gep1 = getelementptr i32, ptr %p, i64 1
%gep2 = getelementptr i64, ptr %p, i64 2
%s = select i1 %c, ptr %gep1, ptr %gep2
ret ptr %s
}
define void @dse(ptr %p) {
; CHECK-LABEL: @dse(
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
; CHECK-NEXT: store i8 1, ptr [[P]], align 1
; CHECK-NEXT: ret void
;
store i32 0, ptr %p
store i8 1, ptr %p
ret void
}
declare void @call_i64(i64)
declare void @call_byval(i64, ptr byval(i64))
define void @call_cast_ptr_to_int(ptr %p) {
; CHECK-LABEL: @call_cast_ptr_to_int(
; CHECK-NEXT: call void @call_i64(ptr [[P:%.*]])
; CHECK-NEXT: ret void
;
call void @call_i64(ptr %p)
ret void
}
define void @call_cast_byval(ptr %p, ptr %p2) {
; CHECK-LABEL: @call_cast_byval(
; CHECK-NEXT: call void @call_byval(ptr [[P:%.*]], ptr byval(double) [[P2:%.*]])
; CHECK-NEXT: ret void
;
call void @call_byval(ptr %p, ptr byval(double) %p2)
ret void
}
declare float @fmodf(float, float)
define i32 @const_fold_call_with_func_type_mismatch() {
; CHECK-LABEL: @const_fold_call_with_func_type_mismatch(
; CHECK-NEXT: [[V:%.*]] = call i32 @fmodf(float 0x40091EB860000000, float 2.000000e+00)
; CHECK-NEXT: ret i32 [[V]]
;
%v = call i32 @fmodf(float 0x40091EB860000000, float 2.000000e+00)
ret i32 %v
}