Files
clang-p2996/llvm/test/Transforms/GVN/non-integral-pointers.ll
Nikita Popov 9f864d2025 Reapply [ConstantFold] Handle vectors in ConstantFoldLoadThroughBitcast()
There seems to be an impedance mismatch between what the type
system considers an aggregate (structs and arrays) and what
constants consider an aggregate (structs, arrays and vectors).

Adjust the type check to consider vectors as well. The previous
version of the patch dropped the type check entirely, but it
turns out that getAggregateElement() does require the constant
to be an aggregate in some edge cases: For Poison/Undef the
getNumElements() API is called, without checking in advance that
we're dealing with an aggregate. Possibly the implementation should
avoid doing that, but for now I'm adding an assert so the next
person doesn't fall into this trap.
2021-03-21 17:48:21 +01:00

455 lines
22 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -gvn -S < %s | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:4:5"
target triple = "x86_64-unknown-linux-gnu"
define void @f0(i1 %alwaysFalse, i64 %val, i64* %loc) {
; CHECK-LABEL: @f0(
; CHECK-NEXT: entry:
; CHECK-NEXT: store i64 [[VAL:%.*]], i64* [[LOC:%.*]], align 8
; CHECK-NEXT: br i1 [[ALWAYSFALSE:%.*]], label [[NEVERTAKEN:%.*]], label [[ALWAYSTAKEN:%.*]]
; CHECK: neverTaken:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast i64* [[LOC]] to i8 addrspace(4)**
; CHECK-NEXT: [[PTR:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)** [[LOC_BC]], align 8
; CHECK-NEXT: store i8 5, i8 addrspace(4)* [[PTR]], align 1
; CHECK-NEXT: ret void
; CHECK: alwaysTaken:
; CHECK-NEXT: ret void
;
entry:
store i64 %val, i64* %loc
br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken
neverTaken:
%loc.bc = bitcast i64* %loc to i8 addrspace(4)**
%ptr = load i8 addrspace(4)*, i8 addrspace(4)** %loc.bc
store i8 5, i8 addrspace(4)* %ptr
ret void
alwaysTaken:
ret void
}
define i64 @f1(i1 %alwaysFalse, i8 addrspace(4)* %val, i8 addrspace(4)** %loc) {
; CHECK-LABEL: @f1(
; CHECK-NEXT: entry:
; CHECK-NEXT: store i8 addrspace(4)* [[VAL:%.*]], i8 addrspace(4)** [[LOC:%.*]], align 8
; CHECK-NEXT: br i1 [[ALWAYSFALSE:%.*]], label [[NEVERTAKEN:%.*]], label [[ALWAYSTAKEN:%.*]]
; CHECK: neverTaken:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast i8 addrspace(4)** [[LOC]] to i64*
; CHECK-NEXT: [[INT:%.*]] = load i64, i64* [[LOC_BC]], align 8
; CHECK-NEXT: ret i64 [[INT]]
; CHECK: alwaysTaken:
; CHECK-NEXT: ret i64 42
;
entry:
store i8 addrspace(4)* %val, i8 addrspace(4)** %loc
br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken
neverTaken:
%loc.bc = bitcast i8 addrspace(4)** %loc to i64*
%int = load i64, i64* %loc.bc
ret i64 %int
alwaysTaken:
ret i64 42
}
;; Note: For terseness, we stop using the %alwaysfalse trick for the
;; tests below and just exercise the bits of forwarding logic directly.
declare void @llvm.memset.p4i8.i64(i8 addrspace(4)* nocapture, i8, i64, i1) nounwind
; Can't forward as the load might be dead. (Pretend we wrote out the alwaysfalse idiom above.)
define i8 addrspace(4)* @neg_forward_memset(i8 addrspace(4)* addrspace(4)* %loc) {
; CHECK-LABEL: @neg_forward_memset(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
; CHECK-NEXT: call void @llvm.memset.p4i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8 7, i64 8, i1 false)
; CHECK-NEXT: [[REF:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC]], align 8
; CHECK-NEXT: ret i8 addrspace(4)* [[REF]]
;
entry:
%loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to i8 addrspace(4)*
call void @llvm.memset.p4i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8 7, i64 8, i1 false)
%ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
ret i8 addrspace(4)* %ref
}
define <1 x i8 addrspace(4)*> @neg_forward_memset_vload(<1 x i8 addrspace(4)*> addrspace(4)* %loc) {
; CHECK-LABEL: @neg_forward_memset_vload(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast <1 x i8 addrspace(4)*> addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
; CHECK-NEXT: call void @llvm.memset.p4i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8 7, i64 8, i1 false)
; CHECK-NEXT: [[REF:%.*]] = load <1 x i8 addrspace(4)*>, <1 x i8 addrspace(4)*> addrspace(4)* [[LOC]], align 8
; CHECK-NEXT: ret <1 x i8 addrspace(4)*> [[REF]]
;
entry:
%loc.bc = bitcast <1 x i8 addrspace(4)*> addrspace(4)* %loc to i8 addrspace(4)*
call void @llvm.memset.p4i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8 7, i64 8, i1 false)
%ref = load <1 x i8 addrspace(4)*>, <1 x i8 addrspace(4)*> addrspace(4)* %loc
ret <1 x i8 addrspace(4)*> %ref
}
; Can forward since we can do so w/o breaking types
define i8 addrspace(4)* @forward_memset_zero(i8 addrspace(4)* addrspace(4)* %loc) {
; CHECK-LABEL: @forward_memset_zero(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
; CHECK-NEXT: call void @llvm.memset.p4i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8 0, i64 8, i1 false)
; CHECK-NEXT: ret i8 addrspace(4)* null
;
entry:
%loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to i8 addrspace(4)*
call void @llvm.memset.p4i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8 0, i64 8, i1 false)
%ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
ret i8 addrspace(4)* %ref
}
; Can't forward as the load might be dead. (Pretend we wrote out the alwaysfalse idiom above.)
define i8 addrspace(4)* @neg_forward_store(i8 addrspace(4)* addrspace(4)* %loc) {
; CHECK-LABEL: @neg_forward_store(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i64 addrspace(4)*
; CHECK-NEXT: store i64 5, i64 addrspace(4)* [[LOC_BC]], align 8
; CHECK-NEXT: [[REF:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC]], align 8
; CHECK-NEXT: ret i8 addrspace(4)* [[REF]]
;
entry:
%loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to i64 addrspace(4)*
store i64 5, i64 addrspace(4)* %loc.bc
%ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
ret i8 addrspace(4)* %ref
}
define <1 x i8 addrspace(4)*> @neg_forward_store_vload(<1 x i8 addrspace(4)*> addrspace(4)* %loc) {
; CHECK-LABEL: @neg_forward_store_vload(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast <1 x i8 addrspace(4)*> addrspace(4)* [[LOC:%.*]] to i64 addrspace(4)*
; CHECK-NEXT: store i64 5, i64 addrspace(4)* [[LOC_BC]], align 8
; CHECK-NEXT: [[REF:%.*]] = load <1 x i8 addrspace(4)*>, <1 x i8 addrspace(4)*> addrspace(4)* [[LOC]], align 8
; CHECK-NEXT: ret <1 x i8 addrspace(4)*> [[REF]]
;
entry:
%loc.bc = bitcast <1 x i8 addrspace(4)*> addrspace(4)* %loc to i64 addrspace(4)*
store i64 5, i64 addrspace(4)* %loc.bc
%ref = load <1 x i8 addrspace(4)*>, <1 x i8 addrspace(4)*> addrspace(4)* %loc
ret <1 x i8 addrspace(4)*> %ref
}
; Nulls have known bit patterns, so we can forward
define i8 addrspace(4)* @forward_store_zero(i8 addrspace(4)* addrspace(4)* %loc) {
; CHECK-LABEL: @forward_store_zero(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i64 addrspace(4)*
; CHECK-NEXT: store i64 0, i64 addrspace(4)* [[LOC_BC]], align 8
; CHECK-NEXT: ret i8 addrspace(4)* null
;
entry:
%loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to i64 addrspace(4)*
store i64 0, i64 addrspace(4)* %loc.bc
%ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
ret i8 addrspace(4)* %ref
}
; Nulls have known bit patterns, so we can forward
define i8 addrspace(4)* @forward_store_zero2(i8 addrspace(4)* addrspace(4)* %loc) {
; CHECK-LABEL: @forward_store_zero2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to <2 x i32> addrspace(4)*
; CHECK-NEXT: store <2 x i32> zeroinitializer, <2 x i32> addrspace(4)* [[LOC_BC]], align 8
; CHECK-NEXT: ret i8 addrspace(4)* null
;
entry:
%loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to <2 x i32> addrspace(4)*
store <2 x i32> zeroinitializer, <2 x i32> addrspace(4)* %loc.bc
%ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
ret i8 addrspace(4)* %ref
}
@NonZeroConstant = constant <4 x i64> <i64 3, i64 3, i64 3, i64 3>
@NonZeroConstant2 = constant <4 x i64 addrspace(4)*> <
i64 addrspace(4)* getelementptr (i64, i64 addrspace(4)* null, i32 3),
i64 addrspace(4)* getelementptr (i64, i64 addrspace(4)* null, i32 3),
i64 addrspace(4)* getelementptr (i64, i64 addrspace(4)* null, i32 3),
i64 addrspace(4)* getelementptr (i64, i64 addrspace(4)* null, i32 3)>
@ZeroConstant = constant <4 x i64> zeroinitializer
; Can't forward as the load might be dead. (Pretend we wrote out the alwaysfalse idiom above.)
define i8 addrspace(4)* @neg_forward_memcopy(i8 addrspace(4)* addrspace(4)* %loc) {
; CHECK-LABEL: @neg_forward_memcopy(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
; CHECK-NEXT: call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64>* @NonZeroConstant to i8*), i64 8, i1 false)
; CHECK-NEXT: [[REF:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC]], align 8
; CHECK-NEXT: ret i8 addrspace(4)* [[REF]]
;
entry:
%loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to i8 addrspace(4)*
%src.bc = bitcast <4 x i64>* @NonZeroConstant to i8*
call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8* %src.bc, i64 8, i1 false)
%ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
ret i8 addrspace(4)* %ref
}
define i64 addrspace(4)* @neg_forward_memcopy2(i64 addrspace(4)* addrspace(4)* %loc) {
; CHECK-LABEL: @neg_forward_memcopy2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast i64 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
; CHECK-NEXT: call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64>* @NonZeroConstant to i8*), i64 8, i1 false)
; CHECK-NEXT: [[REF:%.*]] = load i64 addrspace(4)*, i64 addrspace(4)* addrspace(4)* [[LOC]], align 8
; CHECK-NEXT: ret i64 addrspace(4)* [[REF]]
;
entry:
%loc.bc = bitcast i64 addrspace(4)* addrspace(4)* %loc to i8 addrspace(4)*
%src.bc = bitcast <4 x i64>* @NonZeroConstant to i8*
call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8* %src.bc, i64 8, i1 false)
%ref = load i64 addrspace(4)*, i64 addrspace(4)* addrspace(4)* %loc
ret i64 addrspace(4)* %ref
}
define i8 addrspace(4)* @forward_memcopy(i8 addrspace(4)* addrspace(4)* %loc) {
; CHECK-LABEL: @forward_memcopy(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
; CHECK-NEXT: call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64 addrspace(4)*>* @NonZeroConstant2 to i8*), i64 8, i1 false)
; CHECK-NEXT: ret i8 addrspace(4)* bitcast (i64 addrspace(4)* getelementptr (i64, i64 addrspace(4)* null, i32 3) to i8 addrspace(4)*)
;
entry:
%loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to i8 addrspace(4)*
%src.bc = bitcast <4 x i64 addrspace(4)*>* @NonZeroConstant2 to i8*
call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8* %src.bc, i64 8, i1 false)
%ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
ret i8 addrspace(4)* %ref
}
define i64 addrspace(4)* @forward_memcopy2(i64 addrspace(4)* addrspace(4)* %loc) {
; CHECK-LABEL: @forward_memcopy2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast i64 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
; CHECK-NEXT: call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64 addrspace(4)*>* @NonZeroConstant2 to i8*), i64 8, i1 false)
; CHECK-NEXT: ret i64 addrspace(4)* getelementptr (i64, i64 addrspace(4)* null, i32 3)
;
entry:
%loc.bc = bitcast i64 addrspace(4)* addrspace(4)* %loc to i8 addrspace(4)*
%src.bc = bitcast <4 x i64 addrspace(4)*>* @NonZeroConstant2 to i8*
call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8* %src.bc, i64 8, i1 false)
%ref = load i64 addrspace(4)*, i64 addrspace(4)* addrspace(4)* %loc
ret i64 addrspace(4)* %ref
}
define <1 x i8 addrspace(4)*> @neg_forward_memcpy_vload(<1 x i8 addrspace(4)*> addrspace(4)* %loc) {
; CHECK-LABEL: @neg_forward_memcpy_vload(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast <1 x i8 addrspace(4)*> addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
; CHECK-NEXT: call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64>* @NonZeroConstant to i8*), i64 8, i1 false)
; CHECK-NEXT: [[REF:%.*]] = load <1 x i8 addrspace(4)*>, <1 x i8 addrspace(4)*> addrspace(4)* [[LOC]], align 8
; CHECK-NEXT: ret <1 x i8 addrspace(4)*> [[REF]]
;
entry:
%loc.bc = bitcast <1 x i8 addrspace(4)*> addrspace(4)* %loc to i8 addrspace(4)*
%src.bc = bitcast <4 x i64>* @NonZeroConstant to i8*
call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8* %src.bc, i64 8, i1 false)
%ref = load <1 x i8 addrspace(4)*>, <1 x i8 addrspace(4)*> addrspace(4)* %loc
ret <1 x i8 addrspace(4)*> %ref
}
define <4 x i64 addrspace(4)*> @neg_forward_memcpy_vload2(<4 x i64 addrspace(4)*> addrspace(4)* %loc) {
; CHECK-LABEL: @neg_forward_memcpy_vload2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast <4 x i64 addrspace(4)*> addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
; CHECK-NEXT: call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64>* @NonZeroConstant to i8*), i64 32, i1 false)
; CHECK-NEXT: [[REF:%.*]] = load <4 x i64 addrspace(4)*>, <4 x i64 addrspace(4)*> addrspace(4)* [[LOC]], align 32
; CHECK-NEXT: ret <4 x i64 addrspace(4)*> [[REF]]
;
entry:
%loc.bc = bitcast <4 x i64 addrspace(4)*> addrspace(4)* %loc to i8 addrspace(4)*
%src.bc = bitcast <4 x i64>* @NonZeroConstant to i8*
call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8* %src.bc, i64 32, i1 false)
%ref = load <4 x i64 addrspace(4)*>, <4 x i64 addrspace(4)*> addrspace(4)* %loc
ret <4 x i64 addrspace(4)*> %ref
}
define <4 x i64> @neg_forward_memcpy_vload3(<4 x i64> addrspace(4)* %loc) {
; CHECK-LABEL: @neg_forward_memcpy_vload3(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast <4 x i64> addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
; CHECK-NEXT: call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64 addrspace(4)*>* @NonZeroConstant2 to i8*), i64 32, i1 false)
; CHECK-NEXT: [[REF:%.*]] = load <4 x i64>, <4 x i64> addrspace(4)* [[LOC]], align 32
; CHECK-NEXT: ret <4 x i64> [[REF]]
;
entry:
%loc.bc = bitcast <4 x i64> addrspace(4)* %loc to i8 addrspace(4)*
%src.bc = bitcast <4 x i64 addrspace(4)*>* @NonZeroConstant2 to i8*
call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8* %src.bc, i64 32, i1 false)
%ref = load <4 x i64>, <4 x i64> addrspace(4)* %loc
ret <4 x i64> %ref
}
define <1 x i64 addrspace(4)*> @forward_memcpy_vload3(<4 x i64 addrspace(4)*> addrspace(4)* %loc) {
; CHECK-LABEL: @forward_memcpy_vload3(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast <4 x i64 addrspace(4)*> addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
; CHECK-NEXT: call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64 addrspace(4)*>* @NonZeroConstant2 to i8*), i64 32, i1 false)
; CHECK-NEXT: ret <1 x i64 addrspace(4)*> <i64 addrspace(4)* getelementptr (i64, i64 addrspace(4)* null, i32 3)>
;
entry:
%loc.bc = bitcast <4 x i64 addrspace(4)*> addrspace(4)* %loc to i8 addrspace(4)*
%src.bc = bitcast <4 x i64 addrspace(4)*>* @NonZeroConstant2 to i8*
call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8* %src.bc, i64 32, i1 false)
%ref = load <4 x i64 addrspace(4)*>, <4 x i64 addrspace(4)*> addrspace(4)* %loc
%val = extractelement <4 x i64 addrspace(4)*> %ref, i32 0
%ret = insertelement <1 x i64 addrspace(4)*> undef, i64 addrspace(4)* %val, i32 0
ret <1 x i64 addrspace(4)*> %ret
}
; Can forward since we can do so w/o breaking types
define i8 addrspace(4)* @forward_memcpy_zero(i8 addrspace(4)* addrspace(4)* %loc) {
; CHECK-LABEL: @forward_memcpy_zero(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to i8 addrspace(4)*
; CHECK-NEXT: call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 [[LOC_BC]], i8* bitcast (<4 x i64>* @ZeroConstant to i8*), i64 8, i1 false)
; CHECK-NEXT: ret i8 addrspace(4)* null
;
entry:
%loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to i8 addrspace(4)*
%src.bc = bitcast <4 x i64>* @ZeroConstant to i8*
call void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* align 4 %loc.bc, i8* %src.bc, i64 8, i1 false)
%ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc
ret i8 addrspace(4)* %ref
}
declare void @llvm.memcpy.p4i8.p0i8.i64(i8 addrspace(4)* nocapture, i8* nocapture, i64, i1) nounwind
; Same as the neg_forward_store cases, but for non defs.
; (Pretend we wrote out the alwaysfalse idiom above.)
define i8 addrspace(4)* @neg_store_clobber(i8 addrspace(4)* addrspace(4)* %loc) {
; CHECK-LABEL: @neg_store_clobber(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to <2 x i64> addrspace(4)*
; CHECK-NEXT: store <2 x i64> <i64 4, i64 4>, <2 x i64> addrspace(4)* [[LOC_BC]], align 16
; CHECK-NEXT: [[LOC_OFF:%.*]] = getelementptr i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC]], i64 1
; CHECK-NEXT: [[REF:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC_OFF]], align 8
; CHECK-NEXT: ret i8 addrspace(4)* [[REF]]
;
entry:
%loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to <2 x i64> addrspace(4)*
store <2 x i64> <i64 4, i64 4>, <2 x i64> addrspace(4)* %loc.bc
%loc.off = getelementptr i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc, i64 1
%ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc.off
ret i8 addrspace(4)* %ref
}
declare void @use(<2 x i64>) inaccessiblememonly
; Same as the neg_forward_store cases, but for non defs.
; (Pretend we wrote out the alwaysfalse idiom above.)
define i8 addrspace(4)* @neg_load_clobber(i8 addrspace(4)* addrspace(4)* %loc) {
; CHECK-LABEL: @neg_load_clobber(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to <2 x i64> addrspace(4)*
; CHECK-NEXT: [[V:%.*]] = load <2 x i64>, <2 x i64> addrspace(4)* [[LOC_BC]], align 16
; CHECK-NEXT: call void @use(<2 x i64> [[V]])
; CHECK-NEXT: [[LOC_OFF:%.*]] = getelementptr i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC]], i64 1
; CHECK-NEXT: [[REF:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC_OFF]], align 8
; CHECK-NEXT: ret i8 addrspace(4)* [[REF]]
;
entry:
%loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to <2 x i64> addrspace(4)*
%v = load <2 x i64>, <2 x i64> addrspace(4)* %loc.bc
call void @use(<2 x i64> %v)
%loc.off = getelementptr i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc, i64 1
%ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc.off
ret i8 addrspace(4)* %ref
}
define i8 addrspace(4)* @store_clobber_zero(i8 addrspace(4)* addrspace(4)* %loc) {
; CHECK-LABEL: @store_clobber_zero(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast i8 addrspace(4)* addrspace(4)* [[LOC:%.*]] to <2 x i64> addrspace(4)*
; CHECK-NEXT: store <2 x i64> zeroinitializer, <2 x i64> addrspace(4)* [[LOC_BC]], align 16
; CHECK-NEXT: [[LOC_OFF:%.*]] = getelementptr i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* [[LOC]], i64 1
; CHECK-NEXT: ret i8 addrspace(4)* null
;
entry:
%loc.bc = bitcast i8 addrspace(4)* addrspace(4)* %loc to <2 x i64> addrspace(4)*
store <2 x i64> zeroinitializer, <2 x i64> addrspace(4)* %loc.bc
%loc.off = getelementptr i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc, i64 1
%ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc.off
ret i8 addrspace(4)* %ref
}
define void @smaller_vector(i8* %p) {
; CHECK-LABEL: @smaller_vector(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A:%.*]] = bitcast i8* [[P:%.*]] to <4 x i64 addrspace(4)*>*
; CHECK-NEXT: [[B:%.*]] = bitcast i8* [[P]] to <2 x i64 addrspace(4)*>*
; CHECK-NEXT: [[V4:%.*]] = load <4 x i64 addrspace(4)*>, <4 x i64 addrspace(4)*>* [[A]], align 32
; CHECK-NEXT: [[V2:%.*]] = load <2 x i64 addrspace(4)*>, <2 x i64 addrspace(4)*>* [[B]], align 32
; CHECK-NEXT: call void @use.v2(<2 x i64 addrspace(4)*> [[V2]])
; CHECK-NEXT: call void @use.v4(<4 x i64 addrspace(4)*> [[V4]])
; CHECK-NEXT: ret void
;
entry:
%a = bitcast i8* %p to <4 x i64 addrspace(4)*>*
%b = bitcast i8* %p to <2 x i64 addrspace(4)*>*
%v4 = load <4 x i64 addrspace(4)*>, <4 x i64 addrspace(4)*>* %a, align 32
%v2 = load <2 x i64 addrspace(4)*>, <2 x i64 addrspace(4)*>* %b, align 32
call void @use.v2(<2 x i64 addrspace(4)*> %v2)
call void @use.v4(<4 x i64 addrspace(4)*> %v4)
ret void
}
define i64 addrspace(4)* @vector_extract(i8* %p) {
; CHECK-LABEL: @vector_extract(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A:%.*]] = bitcast i8* [[P:%.*]] to <4 x i64 addrspace(4)*>*
; CHECK-NEXT: [[B:%.*]] = bitcast i8* [[P]] to i64 addrspace(4)**
; CHECK-NEXT: [[V4:%.*]] = load <4 x i64 addrspace(4)*>, <4 x i64 addrspace(4)*>* [[A]], align 32
; CHECK-NEXT: [[RES:%.*]] = load i64 addrspace(4)*, i64 addrspace(4)** [[B]], align 32
; CHECK-NEXT: call void @use.v4(<4 x i64 addrspace(4)*> [[V4]])
; CHECK-NEXT: ret i64 addrspace(4)* [[RES]]
;
entry:
%a = bitcast i8* %p to <4 x i64 addrspace(4)*>*
%b = bitcast i8* %p to i64 addrspace(4)**
%v4 = load <4 x i64 addrspace(4)*>, <4 x i64 addrspace(4)*>* %a, align 32
%res = load i64 addrspace(4)*, i64 addrspace(4)** %b, align 32
call void @use.v4(<4 x i64 addrspace(4)*> %v4)
ret i64 addrspace(4)* %res
}
declare void @use.v2(<2 x i64 addrspace(4)*>)
declare void @use.v4(<4 x i64 addrspace(4)*>)
define i8 addrspace(5)* @multini(i1 %alwaysFalse, i8 addrspace(4)* %val, i8 addrspace(4)** %loc) {
; CHECK-LABEL: @multini(
; CHECK-NEXT: entry:
; CHECK-NEXT: store i8 addrspace(4)* [[VAL:%.*]], i8 addrspace(4)** [[LOC:%.*]], align 8
; CHECK-NEXT: br i1 [[ALWAYSFALSE:%.*]], label [[NEVERTAKEN:%.*]], label [[ALWAYSTAKEN:%.*]]
; CHECK: neverTaken:
; CHECK-NEXT: [[LOC_BC:%.*]] = bitcast i8 addrspace(4)** [[LOC]] to i8 addrspace(5)**
; CHECK-NEXT: [[DIFFERENTAS:%.*]] = load i8 addrspace(5)*, i8 addrspace(5)** [[LOC_BC]], align 8
; CHECK-NEXT: ret i8 addrspace(5)* [[DIFFERENTAS]]
; CHECK: alwaysTaken:
; CHECK-NEXT: ret i8 addrspace(5)* null
;
entry:
store i8 addrspace(4)* %val, i8 addrspace(4)** %loc
br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken
neverTaken:
%loc.bc = bitcast i8 addrspace(4)** %loc to i8 addrspace(5)**
%differentas = load i8 addrspace(5)*, i8 addrspace(5)** %loc.bc
ret i8 addrspace(5)* %differentas
alwaysTaken:
ret i8 addrspace(5)* null
}