Should cover most of the tests for GVN, GVNHoist, GVNSink, GlobalOpt, GlobalSplit, InstCombine, Reassociate, SROA and TailCallElim that had not been updated earlier.
455 lines
22 KiB
LLVM
455 lines
22 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -passes=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
|
|
}
|