Up until now the bottom-up vectorizer pass would not delete the scalar instructions that have external uses after being vectorized, because it lacked the ability to generate extracts from the vectors. With the term "external uses", we refer to uses outside the currently vectorized graph. This patch fixes this. We can now properly handle external uses by extracting from the vectors. This change relies on the recent changes to the DAG's callbacks because the external user may not be within the current DAG's interval.
792 lines
41 KiB
LLVM
792 lines
41 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
|
|
; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" %s -S | FileCheck %s
|
|
; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-revert>" %s -S | FileCheck %s --check-prefix REVERT
|
|
|
|
define void @store_load(ptr %ptr) {
|
|
; CHECK-LABEL: define void @store_load(
|
|
; CHECK-SAME: ptr [[PTR:%.*]]) {
|
|
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META0:![0-9]+]]
|
|
; CHECK-NEXT: store <2 x float> [[VECL]], ptr [[PTR0]], align 4, !sandboxvec [[META0]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; REVERT-LABEL: define void @store_load(
|
|
; REVERT-SAME: ptr [[PTR:%.*]]) {
|
|
; REVERT-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; REVERT-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1, !sandboxvec [[META0:![0-9]+]]
|
|
; REVERT-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4, !sandboxvec [[META0]]
|
|
; REVERT-NEXT: [[LD1:%.*]] = load float, ptr [[PTR1]], align 4, !sandboxvec [[META0]]
|
|
; REVERT-NEXT: store float [[LD0]], ptr [[PTR0]], align 4, !sandboxvec [[META0]]
|
|
; REVERT-NEXT: store float [[LD1]], ptr [[PTR1]], align 4, !sandboxvec [[META0]]
|
|
; REVERT-NEXT: ret void
|
|
;
|
|
%ptr0 = getelementptr float, ptr %ptr, i32 0
|
|
%ptr1 = getelementptr float, ptr %ptr, i32 1
|
|
%ld0 = load float, ptr %ptr0
|
|
%ld1 = load float, ptr %ptr1
|
|
store float %ld0, ptr %ptr0
|
|
store float %ld1, ptr %ptr1
|
|
ret void
|
|
}
|
|
|
|
|
|
define void @store_fpext_load(ptr %ptr) {
|
|
; CHECK-LABEL: define void @store_fpext_load(
|
|
; CHECK-SAME: ptr [[PTR:%.*]]) {
|
|
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; CHECK-NEXT: [[PTRD0:%.*]] = getelementptr double, ptr [[PTR]], i32 0
|
|
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META1:![0-9]+]]
|
|
; CHECK-NEXT: [[VCAST:%.*]] = fpext <2 x float> [[VECL]] to <2 x double>, !sandboxvec [[META1]]
|
|
; CHECK-NEXT: store <2 x double> [[VCAST]], ptr [[PTRD0]], align 8, !sandboxvec [[META1]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; REVERT-LABEL: define void @store_fpext_load(
|
|
; REVERT-SAME: ptr [[PTR:%.*]]) {
|
|
; REVERT-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; REVERT-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1, !sandboxvec [[META1:![0-9]+]]
|
|
; REVERT-NEXT: [[PTRD0:%.*]] = getelementptr double, ptr [[PTR]], i32 0
|
|
; REVERT-NEXT: [[PTRD1:%.*]] = getelementptr double, ptr [[PTR]], i32 1, !sandboxvec [[META1]]
|
|
; REVERT-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4, !sandboxvec [[META1]]
|
|
; REVERT-NEXT: [[LD1:%.*]] = load float, ptr [[PTR1]], align 4, !sandboxvec [[META1]]
|
|
; REVERT-NEXT: [[FPEXT0:%.*]] = fpext float [[LD0]] to double, !sandboxvec [[META1]]
|
|
; REVERT-NEXT: [[FPEXT1:%.*]] = fpext float [[LD1]] to double, !sandboxvec [[META1]]
|
|
; REVERT-NEXT: store double [[FPEXT0]], ptr [[PTRD0]], align 8, !sandboxvec [[META1]]
|
|
; REVERT-NEXT: store double [[FPEXT1]], ptr [[PTRD1]], align 8, !sandboxvec [[META1]]
|
|
; REVERT-NEXT: ret void
|
|
;
|
|
%ptr0 = getelementptr float, ptr %ptr, i32 0
|
|
%ptr1 = getelementptr float, ptr %ptr, i32 1
|
|
%ptrd0 = getelementptr double, ptr %ptr, i32 0
|
|
%ptrd1 = getelementptr double, ptr %ptr, i32 1
|
|
%ld0 = load float, ptr %ptr0
|
|
%ld1 = load float, ptr %ptr1
|
|
%fpext0 = fpext float %ld0 to double
|
|
%fpext1 = fpext float %ld1 to double
|
|
store double %fpext0, ptr %ptrd0
|
|
store double %fpext1, ptr %ptrd1
|
|
ret void
|
|
}
|
|
|
|
define void @store_fcmp_zext_load(ptr %ptr) {
|
|
; CHECK-LABEL: define void @store_fcmp_zext_load(
|
|
; CHECK-SAME: ptr [[PTR:%.*]]) {
|
|
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; CHECK-NEXT: [[PTRB0:%.*]] = getelementptr i32, ptr [[PTR]], i32 0
|
|
; CHECK-NEXT: [[VECL1:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META2:![0-9]+]]
|
|
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META2]]
|
|
; CHECK-NEXT: [[VCMP:%.*]] = fcmp ogt <2 x float> [[VECL]], [[VECL1]], !sandboxvec [[META2]]
|
|
; CHECK-NEXT: [[VCAST:%.*]] = zext <2 x i1> [[VCMP]] to <2 x i32>, !sandboxvec [[META2]]
|
|
; CHECK-NEXT: store <2 x i32> [[VCAST]], ptr [[PTRB0]], align 4, !sandboxvec [[META2]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; REVERT-LABEL: define void @store_fcmp_zext_load(
|
|
; REVERT-SAME: ptr [[PTR:%.*]]) {
|
|
; REVERT-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; REVERT-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1, !sandboxvec [[META2:![0-9]+]]
|
|
; REVERT-NEXT: [[PTRB0:%.*]] = getelementptr i32, ptr [[PTR]], i32 0
|
|
; REVERT-NEXT: [[PTRB1:%.*]] = getelementptr i32, ptr [[PTR]], i32 1, !sandboxvec [[META2]]
|
|
; REVERT-NEXT: [[LDB0:%.*]] = load float, ptr [[PTR0]], align 4, !sandboxvec [[META2]]
|
|
; REVERT-NEXT: [[LDB1:%.*]] = load float, ptr [[PTR1]], align 4, !sandboxvec [[META2]]
|
|
; REVERT-NEXT: [[LDA0:%.*]] = load float, ptr [[PTR0]], align 4, !sandboxvec [[META2]]
|
|
; REVERT-NEXT: [[LDA1:%.*]] = load float, ptr [[PTR1]], align 4, !sandboxvec [[META2]]
|
|
; REVERT-NEXT: [[FCMP0:%.*]] = fcmp ogt float [[LDA0]], [[LDB0]], !sandboxvec [[META2]]
|
|
; REVERT-NEXT: [[FCMP1:%.*]] = fcmp ogt float [[LDA1]], [[LDB1]], !sandboxvec [[META2]]
|
|
; REVERT-NEXT: [[ZEXT0:%.*]] = zext i1 [[FCMP0]] to i32, !sandboxvec [[META2]]
|
|
; REVERT-NEXT: [[ZEXT1:%.*]] = zext i1 [[FCMP1]] to i32, !sandboxvec [[META2]]
|
|
; REVERT-NEXT: store i32 [[ZEXT0]], ptr [[PTRB0]], align 4, !sandboxvec [[META2]]
|
|
; REVERT-NEXT: store i32 [[ZEXT1]], ptr [[PTRB1]], align 4, !sandboxvec [[META2]]
|
|
; REVERT-NEXT: ret void
|
|
;
|
|
%ptr0 = getelementptr float, ptr %ptr, i32 0
|
|
%ptr1 = getelementptr float, ptr %ptr, i32 1
|
|
%ptrb0 = getelementptr i32, ptr %ptr, i32 0
|
|
%ptrb1 = getelementptr i32, ptr %ptr, i32 1
|
|
%ldB0 = load float, ptr %ptr0
|
|
%ldB1 = load float, ptr %ptr1
|
|
%ldA0 = load float, ptr %ptr0
|
|
%ldA1 = load float, ptr %ptr1
|
|
%fcmp0 = fcmp ogt float %ldA0, %ldB0
|
|
%fcmp1 = fcmp ogt float %ldA1, %ldB1
|
|
%zext0 = zext i1 %fcmp0 to i32
|
|
%zext1 = zext i1 %fcmp1 to i32
|
|
store i32 %zext0, ptr %ptrb0
|
|
store i32 %zext1, ptr %ptrb1
|
|
ret void
|
|
}
|
|
|
|
define void @store_fadd_load(ptr %ptr) {
|
|
; CHECK-LABEL: define void @store_fadd_load(
|
|
; CHECK-SAME: ptr [[PTR:%.*]]) {
|
|
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; CHECK-NEXT: [[VECL1:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META3:![0-9]+]]
|
|
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META3]]
|
|
; CHECK-NEXT: [[VEC:%.*]] = fadd <2 x float> [[VECL]], [[VECL1]], !sandboxvec [[META3]]
|
|
; CHECK-NEXT: store <2 x float> [[VEC]], ptr [[PTR0]], align 4, !sandboxvec [[META3]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; REVERT-LABEL: define void @store_fadd_load(
|
|
; REVERT-SAME: ptr [[PTR:%.*]]) {
|
|
; REVERT-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; REVERT-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1, !sandboxvec [[META3:![0-9]+]]
|
|
; REVERT-NEXT: [[LDA0:%.*]] = load float, ptr [[PTR0]], align 4, !sandboxvec [[META3]]
|
|
; REVERT-NEXT: [[LDA1:%.*]] = load float, ptr [[PTR1]], align 4, !sandboxvec [[META3]]
|
|
; REVERT-NEXT: [[LDB0:%.*]] = load float, ptr [[PTR0]], align 4, !sandboxvec [[META3]]
|
|
; REVERT-NEXT: [[LDB1:%.*]] = load float, ptr [[PTR1]], align 4, !sandboxvec [[META3]]
|
|
; REVERT-NEXT: [[FADD0:%.*]] = fadd float [[LDA0]], [[LDB0]], !sandboxvec [[META3]]
|
|
; REVERT-NEXT: [[FADD1:%.*]] = fadd float [[LDA1]], [[LDB1]], !sandboxvec [[META3]]
|
|
; REVERT-NEXT: store float [[FADD0]], ptr [[PTR0]], align 4, !sandboxvec [[META3]]
|
|
; REVERT-NEXT: store float [[FADD1]], ptr [[PTR1]], align 4, !sandboxvec [[META3]]
|
|
; REVERT-NEXT: ret void
|
|
;
|
|
%ptr0 = getelementptr float, ptr %ptr, i32 0
|
|
%ptr1 = getelementptr float, ptr %ptr, i32 1
|
|
%ldA0 = load float, ptr %ptr0
|
|
%ldA1 = load float, ptr %ptr1
|
|
%ldB0 = load float, ptr %ptr0
|
|
%ldB1 = load float, ptr %ptr1
|
|
%fadd0 = fadd float %ldA0, %ldB0
|
|
%fadd1 = fadd float %ldA1, %ldB1
|
|
store float %fadd0, ptr %ptr0
|
|
store float %fadd1, ptr %ptr1
|
|
ret void
|
|
}
|
|
|
|
define void @store_fneg_load(ptr %ptr) {
|
|
; CHECK-LABEL: define void @store_fneg_load(
|
|
; CHECK-SAME: ptr [[PTR:%.*]]) {
|
|
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META4:![0-9]+]]
|
|
; CHECK-NEXT: [[VEC:%.*]] = fneg <2 x float> [[VECL]], !sandboxvec [[META4]]
|
|
; CHECK-NEXT: store <2 x float> [[VEC]], ptr [[PTR0]], align 4, !sandboxvec [[META4]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; REVERT-LABEL: define void @store_fneg_load(
|
|
; REVERT-SAME: ptr [[PTR:%.*]]) {
|
|
; REVERT-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; REVERT-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1, !sandboxvec [[META4:![0-9]+]]
|
|
; REVERT-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4, !sandboxvec [[META4]]
|
|
; REVERT-NEXT: [[LD1:%.*]] = load float, ptr [[PTR1]], align 4, !sandboxvec [[META4]]
|
|
; REVERT-NEXT: [[FNEG0:%.*]] = fneg float [[LD0]], !sandboxvec [[META4]]
|
|
; REVERT-NEXT: [[FNEG1:%.*]] = fneg float [[LD1]], !sandboxvec [[META4]]
|
|
; REVERT-NEXT: store float [[FNEG0]], ptr [[PTR0]], align 4, !sandboxvec [[META4]]
|
|
; REVERT-NEXT: store float [[FNEG1]], ptr [[PTR1]], align 4, !sandboxvec [[META4]]
|
|
; REVERT-NEXT: ret void
|
|
;
|
|
%ptr0 = getelementptr float, ptr %ptr, i32 0
|
|
%ptr1 = getelementptr float, ptr %ptr, i32 1
|
|
%ld0 = load float, ptr %ptr0
|
|
%ld1 = load float, ptr %ptr1
|
|
%fneg0 = fneg float %ld0
|
|
%fneg1 = fneg float %ld1
|
|
store float %fneg0, ptr %ptr0
|
|
store float %fneg1, ptr %ptr1
|
|
ret void
|
|
}
|
|
|
|
define float @scalars_with_external_uses_not_dead(ptr %ptr) {
|
|
; CHECK-LABEL: define float @scalars_with_external_uses_not_dead(
|
|
; CHECK-SAME: ptr [[PTR:%.*]]) {
|
|
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META5:![0-9]+]]
|
|
; CHECK-NEXT: [[LD0:%.*]] = extractelement <2 x float> [[VECL]], i32 0, !sandboxvec [[META5]]
|
|
; CHECK-NEXT: [[LD1:%.*]] = extractelement <2 x float> [[VECL]], i32 1, !sandboxvec [[META5]]
|
|
; CHECK-NEXT: store <2 x float> [[VECL]], ptr [[PTR0]], align 4, !sandboxvec [[META5]]
|
|
; CHECK-NEXT: [[USER:%.*]] = fneg float [[LD1]]
|
|
; CHECK-NEXT: ret float [[LD0]]
|
|
;
|
|
; REVERT-LABEL: define float @scalars_with_external_uses_not_dead(
|
|
; REVERT-SAME: ptr [[PTR:%.*]]) {
|
|
; REVERT-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; REVERT-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1, !sandboxvec [[META5:![0-9]+]]
|
|
; REVERT-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4, !sandboxvec [[META5]]
|
|
; REVERT-NEXT: [[LD1:%.*]] = load float, ptr [[PTR1]], align 4, !sandboxvec [[META5]]
|
|
; REVERT-NEXT: store float [[LD0]], ptr [[PTR0]], align 4, !sandboxvec [[META5]]
|
|
; REVERT-NEXT: store float [[LD1]], ptr [[PTR1]], align 4, !sandboxvec [[META5]]
|
|
; REVERT-NEXT: [[USER:%.*]] = fneg float [[LD1]]
|
|
; REVERT-NEXT: ret float [[LD0]]
|
|
;
|
|
%ptr0 = getelementptr float, ptr %ptr, i32 0
|
|
%ptr1 = getelementptr float, ptr %ptr, i32 1
|
|
%ld0 = load float, ptr %ptr0
|
|
%ld1 = load float, ptr %ptr1
|
|
store float %ld0, ptr %ptr0
|
|
store float %ld1, ptr %ptr1
|
|
%user = fneg float %ld1
|
|
ret float %ld0
|
|
}
|
|
|
|
define void @pack_scalars(ptr %ptr, ptr %ptr2) {
|
|
; CHECK-LABEL: define void @pack_scalars(
|
|
; CHECK-SAME: ptr [[PTR:%.*]], ptr [[PTR2:%.*]]) {
|
|
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; CHECK-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
|
|
; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[PTR2]], align 4
|
|
; CHECK-NEXT: [[PACK:%.*]] = insertelement <2 x float> poison, float [[LD0]], i32 0, !sandboxvec [[META6:![0-9]+]]
|
|
; CHECK-NEXT: [[PACK1:%.*]] = insertelement <2 x float> [[PACK]], float [[LD1]], i32 1, !sandboxvec [[META6]]
|
|
; CHECK-NEXT: store <2 x float> [[PACK1]], ptr [[PTR0]], align 4, !sandboxvec [[META6]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; REVERT-LABEL: define void @pack_scalars(
|
|
; REVERT-SAME: ptr [[PTR:%.*]], ptr [[PTR2:%.*]]) {
|
|
; REVERT-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; REVERT-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1, !sandboxvec [[META6:![0-9]+]]
|
|
; REVERT-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
|
|
; REVERT-NEXT: [[LD1:%.*]] = load float, ptr [[PTR2]], align 4
|
|
; REVERT-NEXT: store float [[LD0]], ptr [[PTR0]], align 4, !sandboxvec [[META6]]
|
|
; REVERT-NEXT: store float [[LD1]], ptr [[PTR1]], align 4, !sandboxvec [[META6]]
|
|
; REVERT-NEXT: ret void
|
|
;
|
|
%ptr0 = getelementptr float, ptr %ptr, i32 0
|
|
%ptr1 = getelementptr float, ptr %ptr, i32 1
|
|
%ld0 = load float, ptr %ptr0
|
|
%ld1 = load float, ptr %ptr2
|
|
store float %ld0, ptr %ptr0
|
|
store float %ld1, ptr %ptr1
|
|
ret void
|
|
}
|
|
|
|
declare void @foo()
|
|
define void @cant_vectorize_seeds(ptr %ptr) {
|
|
; CHECK-LABEL: define void @cant_vectorize_seeds(
|
|
; CHECK-SAME: ptr [[PTR:%.*]]) {
|
|
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
|
|
; CHECK-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
|
|
; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
|
|
; CHECK-NEXT: store float [[LD1]], ptr [[PTR1]], align 4, !sandboxvec [[META7:![0-9]+]]
|
|
; CHECK-NEXT: call void @foo()
|
|
; CHECK-NEXT: store float [[LD1]], ptr [[PTR1]], align 4, !sandboxvec [[META7]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; REVERT-LABEL: define void @cant_vectorize_seeds(
|
|
; REVERT-SAME: ptr [[PTR:%.*]]) {
|
|
; REVERT-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; REVERT-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
|
|
; REVERT-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
|
|
; REVERT-NEXT: [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
|
|
; REVERT-NEXT: store float [[LD1]], ptr [[PTR1]], align 4, !sandboxvec [[META7:![0-9]+]]
|
|
; REVERT-NEXT: call void @foo()
|
|
; REVERT-NEXT: store float [[LD1]], ptr [[PTR1]], align 4, !sandboxvec [[META7]]
|
|
; REVERT-NEXT: ret void
|
|
;
|
|
%ptr0 = getelementptr float, ptr %ptr, i32 0
|
|
%ptr1 = getelementptr float, ptr %ptr, i32 1
|
|
%ld0 = load float, ptr %ptr0
|
|
%ld1 = load float, ptr %ptr1
|
|
store float %ld1, ptr %ptr1
|
|
call void @foo() ; This call blocks scheduling of the store seeds.
|
|
store float %ld1, ptr %ptr1
|
|
ret void
|
|
}
|
|
|
|
define void @pack_vectors(ptr %ptr, ptr %ptr2) {
|
|
; CHECK-LABEL: define void @pack_vectors(
|
|
; CHECK-SAME: ptr [[PTR:%.*]], ptr [[PTR2:%.*]]) {
|
|
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr <2 x float>, ptr [[PTR]], i32 0
|
|
; CHECK-NEXT: [[LD0:%.*]] = load <2 x float>, ptr [[PTR0]], align 8
|
|
; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[PTR2]], align 4
|
|
; CHECK-NEXT: [[VPACK:%.*]] = extractelement <2 x float> [[LD0]], i32 0, !sandboxvec [[META8:![0-9]+]]
|
|
; CHECK-NEXT: [[VPACK1:%.*]] = insertelement <3 x float> poison, float [[VPACK]], i32 0, !sandboxvec [[META8]]
|
|
; CHECK-NEXT: [[VPACK2:%.*]] = extractelement <2 x float> [[LD0]], i32 1, !sandboxvec [[META8]]
|
|
; CHECK-NEXT: [[VPACK3:%.*]] = insertelement <3 x float> [[VPACK1]], float [[VPACK2]], i32 1, !sandboxvec [[META8]]
|
|
; CHECK-NEXT: [[PACK:%.*]] = insertelement <3 x float> [[VPACK3]], float [[LD1]], i32 2, !sandboxvec [[META8]]
|
|
; CHECK-NEXT: store <3 x float> [[PACK]], ptr [[PTR0]], align 8, !sandboxvec [[META8]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; REVERT-LABEL: define void @pack_vectors(
|
|
; REVERT-SAME: ptr [[PTR:%.*]], ptr [[PTR2:%.*]]) {
|
|
; REVERT-NEXT: [[PTR0:%.*]] = getelementptr <2 x float>, ptr [[PTR]], i32 0
|
|
; REVERT-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 2, !sandboxvec [[META8:![0-9]+]]
|
|
; REVERT-NEXT: [[LD0:%.*]] = load <2 x float>, ptr [[PTR0]], align 8
|
|
; REVERT-NEXT: [[LD1:%.*]] = load float, ptr [[PTR2]], align 4
|
|
; REVERT-NEXT: store <2 x float> [[LD0]], ptr [[PTR0]], align 8, !sandboxvec [[META8]]
|
|
; REVERT-NEXT: store float [[LD1]], ptr [[PTR1]], align 4, !sandboxvec [[META8]]
|
|
; REVERT-NEXT: ret void
|
|
;
|
|
%ptr0 = getelementptr <2 x float>, ptr %ptr, i32 0
|
|
%ptr1 = getelementptr float, ptr %ptr, i32 2
|
|
%ld0 = load <2 x float>, ptr %ptr0
|
|
%ld1 = load float, ptr %ptr2
|
|
store <2 x float> %ld0, ptr %ptr0
|
|
store float %ld1, ptr %ptr1
|
|
ret void
|
|
}
|
|
|
|
define void @diamond(ptr %ptr) {
|
|
; CHECK-LABEL: define void @diamond(
|
|
; CHECK-SAME: ptr [[PTR:%.*]]) {
|
|
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META9:![0-9]+]]
|
|
; CHECK-NEXT: [[VEC:%.*]] = fsub <2 x float> [[VECL]], [[VECL]], !sandboxvec [[META9]]
|
|
; CHECK-NEXT: store <2 x float> [[VEC]], ptr [[PTR0]], align 4, !sandboxvec [[META9]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; REVERT-LABEL: define void @diamond(
|
|
; REVERT-SAME: ptr [[PTR:%.*]]) {
|
|
; REVERT-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; REVERT-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1, !sandboxvec [[META9:![0-9]+]]
|
|
; REVERT-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4, !sandboxvec [[META9]]
|
|
; REVERT-NEXT: [[LD1:%.*]] = load float, ptr [[PTR1]], align 4, !sandboxvec [[META9]]
|
|
; REVERT-NEXT: [[SUB0:%.*]] = fsub float [[LD0]], [[LD0]], !sandboxvec [[META9]]
|
|
; REVERT-NEXT: [[SUB1:%.*]] = fsub float [[LD1]], [[LD1]], !sandboxvec [[META9]]
|
|
; REVERT-NEXT: store float [[SUB0]], ptr [[PTR0]], align 4, !sandboxvec [[META9]]
|
|
; REVERT-NEXT: store float [[SUB1]], ptr [[PTR1]], align 4, !sandboxvec [[META9]]
|
|
; REVERT-NEXT: ret void
|
|
;
|
|
%ptr0 = getelementptr float, ptr %ptr, i32 0
|
|
%ptr1 = getelementptr float, ptr %ptr, i32 1
|
|
%ld0 = load float, ptr %ptr0
|
|
%ld1 = load float, ptr %ptr1
|
|
%sub0 = fsub float %ld0, %ld0
|
|
%sub1 = fsub float %ld1, %ld1
|
|
store float %sub0, ptr %ptr0
|
|
store float %sub1, ptr %ptr1
|
|
ret void
|
|
}
|
|
|
|
define void @diamondWithShuffle(ptr %ptr) {
|
|
; CHECK-LABEL: define void @diamondWithShuffle(
|
|
; CHECK-SAME: ptr [[PTR:%.*]]) {
|
|
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META10:![0-9]+]]
|
|
; CHECK-NEXT: [[VSHUF:%.*]] = shufflevector <2 x float> [[VECL]], <2 x float> [[VECL]], <2 x i32> <i32 1, i32 0>, !sandboxvec [[META10]]
|
|
; CHECK-NEXT: [[VEC:%.*]] = fsub <2 x float> [[VECL]], [[VSHUF]], !sandboxvec [[META10]]
|
|
; CHECK-NEXT: store <2 x float> [[VEC]], ptr [[PTR0]], align 4, !sandboxvec [[META10]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; REVERT-LABEL: define void @diamondWithShuffle(
|
|
; REVERT-SAME: ptr [[PTR:%.*]]) {
|
|
; REVERT-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; REVERT-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1, !sandboxvec [[META10:![0-9]+]]
|
|
; REVERT-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4, !sandboxvec [[META10]]
|
|
; REVERT-NEXT: [[LD1:%.*]] = load float, ptr [[PTR1]], align 4, !sandboxvec [[META10]]
|
|
; REVERT-NEXT: [[SUB0:%.*]] = fsub float [[LD0]], [[LD1]], !sandboxvec [[META10]]
|
|
; REVERT-NEXT: [[SUB1:%.*]] = fsub float [[LD1]], [[LD0]], !sandboxvec [[META10]]
|
|
; REVERT-NEXT: store float [[SUB0]], ptr [[PTR0]], align 4, !sandboxvec [[META10]]
|
|
; REVERT-NEXT: store float [[SUB1]], ptr [[PTR1]], align 4, !sandboxvec [[META10]]
|
|
; REVERT-NEXT: ret void
|
|
;
|
|
%ptr0 = getelementptr float, ptr %ptr, i32 0
|
|
%ptr1 = getelementptr float, ptr %ptr, i32 1
|
|
%ld0 = load float, ptr %ptr0
|
|
%ld1 = load float, ptr %ptr1
|
|
%sub0 = fsub float %ld0, %ld1
|
|
%sub1 = fsub float %ld1, %ld0
|
|
store float %sub0, ptr %ptr0
|
|
store float %sub1, ptr %ptr1
|
|
ret void
|
|
}
|
|
|
|
; Same but with <2 x float> elements instead of scalars.
|
|
define void @diamondWithShuffleFromVec(ptr %ptr) {
|
|
; CHECK-LABEL: define void @diamondWithShuffleFromVec(
|
|
; CHECK-SAME: ptr [[PTR:%.*]]) {
|
|
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr <2 x float>, ptr [[PTR]], i32 0
|
|
; CHECK-NEXT: [[VECL:%.*]] = load <4 x float>, ptr [[PTR0]], align 8, !sandboxvec [[META11:![0-9]+]]
|
|
; CHECK-NEXT: [[VSHUF:%.*]] = shufflevector <4 x float> [[VECL]], <4 x float> [[VECL]], <4 x i32> <i32 2, i32 3, i32 0, i32 1>, !sandboxvec [[META11]]
|
|
; CHECK-NEXT: [[VEC:%.*]] = fsub <4 x float> [[VECL]], [[VSHUF]], !sandboxvec [[META11]]
|
|
; CHECK-NEXT: store <4 x float> [[VEC]], ptr [[PTR0]], align 8, !sandboxvec [[META11]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; REVERT-LABEL: define void @diamondWithShuffleFromVec(
|
|
; REVERT-SAME: ptr [[PTR:%.*]]) {
|
|
; REVERT-NEXT: [[PTR0:%.*]] = getelementptr <2 x float>, ptr [[PTR]], i32 0
|
|
; REVERT-NEXT: [[PTR1:%.*]] = getelementptr <2 x float>, ptr [[PTR]], i32 1, !sandboxvec [[META11:![0-9]+]]
|
|
; REVERT-NEXT: [[LD0:%.*]] = load <2 x float>, ptr [[PTR0]], align 8, !sandboxvec [[META11]]
|
|
; REVERT-NEXT: [[LD1:%.*]] = load <2 x float>, ptr [[PTR1]], align 8, !sandboxvec [[META11]]
|
|
; REVERT-NEXT: [[SUB0:%.*]] = fsub <2 x float> [[LD0]], [[LD1]], !sandboxvec [[META11]]
|
|
; REVERT-NEXT: [[SUB1:%.*]] = fsub <2 x float> [[LD1]], [[LD0]], !sandboxvec [[META11]]
|
|
; REVERT-NEXT: store <2 x float> [[SUB0]], ptr [[PTR0]], align 8, !sandboxvec [[META11]]
|
|
; REVERT-NEXT: store <2 x float> [[SUB1]], ptr [[PTR1]], align 8, !sandboxvec [[META11]]
|
|
; REVERT-NEXT: ret void
|
|
;
|
|
%ptr0 = getelementptr <2 x float>, ptr %ptr, i32 0
|
|
%ptr1 = getelementptr <2 x float>, ptr %ptr, i32 1
|
|
%ld0 = load <2 x float>, ptr %ptr0
|
|
%ld1 = load <2 x float>, ptr %ptr1
|
|
%sub0 = fsub <2 x float> %ld0, %ld1
|
|
%sub1 = fsub <2 x float> %ld1, %ld0
|
|
store <2 x float> %sub0, ptr %ptr0
|
|
store <2 x float> %sub1, ptr %ptr1
|
|
ret void
|
|
}
|
|
|
|
define void @diamondMultiInput(ptr %ptr, ptr %ptrX) {
|
|
; CHECK-LABEL: define void @diamondMultiInput(
|
|
; CHECK-SAME: ptr [[PTR:%.*]], ptr [[PTRX:%.*]]) {
|
|
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; CHECK-NEXT: [[LDX:%.*]] = load float, ptr [[PTRX]], align 4
|
|
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META12:![0-9]+]]
|
|
; CHECK-NEXT: [[VINS:%.*]] = insertelement <2 x float> poison, float [[LDX]], i32 0, !sandboxvec [[META12]]
|
|
; CHECK-NEXT: [[VEXT:%.*]] = extractelement <2 x float> [[VECL]], i32 0, !sandboxvec [[META12]]
|
|
; CHECK-NEXT: [[VINS1:%.*]] = insertelement <2 x float> [[VINS]], float [[VEXT]], i32 1, !sandboxvec [[META12]]
|
|
; CHECK-NEXT: [[VEC:%.*]] = fsub <2 x float> [[VECL]], [[VINS1]], !sandboxvec [[META12]]
|
|
; CHECK-NEXT: store <2 x float> [[VEC]], ptr [[PTR0]], align 4, !sandboxvec [[META12]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; REVERT-LABEL: define void @diamondMultiInput(
|
|
; REVERT-SAME: ptr [[PTR:%.*]], ptr [[PTRX:%.*]]) {
|
|
; REVERT-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; REVERT-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1, !sandboxvec [[META12:![0-9]+]]
|
|
; REVERT-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4, !sandboxvec [[META12]]
|
|
; REVERT-NEXT: [[LD1:%.*]] = load float, ptr [[PTR1]], align 4, !sandboxvec [[META12]]
|
|
; REVERT-NEXT: [[LDX:%.*]] = load float, ptr [[PTRX]], align 4
|
|
; REVERT-NEXT: [[SUB0:%.*]] = fsub float [[LD0]], [[LDX]], !sandboxvec [[META12]]
|
|
; REVERT-NEXT: [[SUB1:%.*]] = fsub float [[LD1]], [[LD0]], !sandboxvec [[META12]]
|
|
; REVERT-NEXT: store float [[SUB0]], ptr [[PTR0]], align 4, !sandboxvec [[META12]]
|
|
; REVERT-NEXT: store float [[SUB1]], ptr [[PTR1]], align 4, !sandboxvec [[META12]]
|
|
; REVERT-NEXT: ret void
|
|
;
|
|
%ptr0 = getelementptr float, ptr %ptr, i32 0
|
|
%ptr1 = getelementptr float, ptr %ptr, i32 1
|
|
%ld0 = load float, ptr %ptr0
|
|
%ld1 = load float, ptr %ptr1
|
|
|
|
%ldX = load float, ptr %ptrX
|
|
|
|
%sub0 = fsub float %ld0, %ldX
|
|
%sub1 = fsub float %ld1, %ld0
|
|
store float %sub0, ptr %ptr0
|
|
store float %sub1, ptr %ptr1
|
|
ret void
|
|
}
|
|
|
|
; Same but vectorizing <2 x float> vectors instead of scalars.
|
|
define void @diamondMultiInputVector(ptr %ptr, ptr %ptrX) {
|
|
; CHECK-LABEL: define void @diamondMultiInputVector(
|
|
; CHECK-SAME: ptr [[PTR:%.*]], ptr [[PTRX:%.*]]) {
|
|
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr <2 x float>, ptr [[PTR]], i32 0
|
|
; CHECK-NEXT: [[LDX:%.*]] = load <2 x float>, ptr [[PTRX]], align 8
|
|
; CHECK-NEXT: [[VECL:%.*]] = load <4 x float>, ptr [[PTR0]], align 8, !sandboxvec [[META13:![0-9]+]]
|
|
; CHECK-NEXT: [[VEXT:%.*]] = extractelement <2 x float> [[LDX]], i32 0, !sandboxvec [[META13]]
|
|
; CHECK-NEXT: [[VINS:%.*]] = insertelement <4 x float> poison, float [[VEXT]], i32 0, !sandboxvec [[META13]]
|
|
; CHECK-NEXT: [[VEXT1:%.*]] = extractelement <2 x float> [[LDX]], i32 1, !sandboxvec [[META13]]
|
|
; CHECK-NEXT: [[VINS2:%.*]] = insertelement <4 x float> [[VINS]], float [[VEXT1]], i32 1, !sandboxvec [[META13]]
|
|
; CHECK-NEXT: [[VEXT3:%.*]] = extractelement <4 x float> [[VECL]], i32 0, !sandboxvec [[META13]]
|
|
; CHECK-NEXT: [[VINS4:%.*]] = insertelement <4 x float> [[VINS2]], float [[VEXT3]], i32 2, !sandboxvec [[META13]]
|
|
; CHECK-NEXT: [[VEXT5:%.*]] = extractelement <4 x float> [[VECL]], i32 1, !sandboxvec [[META13]]
|
|
; CHECK-NEXT: [[VINS6:%.*]] = insertelement <4 x float> [[VINS4]], float [[VEXT5]], i32 3, !sandboxvec [[META13]]
|
|
; CHECK-NEXT: [[VEC:%.*]] = fsub <4 x float> [[VECL]], [[VINS6]], !sandboxvec [[META13]]
|
|
; CHECK-NEXT: store <4 x float> [[VEC]], ptr [[PTR0]], align 8, !sandboxvec [[META13]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; REVERT-LABEL: define void @diamondMultiInputVector(
|
|
; REVERT-SAME: ptr [[PTR:%.*]], ptr [[PTRX:%.*]]) {
|
|
; REVERT-NEXT: [[PTR0:%.*]] = getelementptr <2 x float>, ptr [[PTR]], i32 0
|
|
; REVERT-NEXT: [[PTR1:%.*]] = getelementptr <2 x float>, ptr [[PTR]], i32 1, !sandboxvec [[META13:![0-9]+]]
|
|
; REVERT-NEXT: [[LD0:%.*]] = load <2 x float>, ptr [[PTR0]], align 8, !sandboxvec [[META13]]
|
|
; REVERT-NEXT: [[LD1:%.*]] = load <2 x float>, ptr [[PTR1]], align 8, !sandboxvec [[META13]]
|
|
; REVERT-NEXT: [[LDX:%.*]] = load <2 x float>, ptr [[PTRX]], align 8
|
|
; REVERT-NEXT: [[SUB0:%.*]] = fsub <2 x float> [[LD0]], [[LDX]], !sandboxvec [[META13]]
|
|
; REVERT-NEXT: [[SUB1:%.*]] = fsub <2 x float> [[LD1]], [[LD0]], !sandboxvec [[META13]]
|
|
; REVERT-NEXT: store <2 x float> [[SUB0]], ptr [[PTR0]], align 8, !sandboxvec [[META13]]
|
|
; REVERT-NEXT: store <2 x float> [[SUB1]], ptr [[PTR1]], align 8, !sandboxvec [[META13]]
|
|
; REVERT-NEXT: ret void
|
|
;
|
|
%ptr0 = getelementptr <2 x float>, ptr %ptr, i32 0
|
|
%ptr1 = getelementptr <2 x float>, ptr %ptr, i32 1
|
|
%ld0 = load <2 x float>, ptr %ptr0
|
|
%ld1 = load <2 x float>, ptr %ptr1
|
|
|
|
%ldX = load <2 x float>, ptr %ptrX
|
|
|
|
%sub0 = fsub <2 x float> %ld0, %ldX
|
|
%sub1 = fsub <2 x float> %ld1, %ld0
|
|
store <2 x float> %sub0, ptr %ptr0
|
|
store <2 x float> %sub1, ptr %ptr1
|
|
ret void
|
|
}
|
|
|
|
define void @diamondWithConstantVector(ptr %ptr) {
|
|
; CHECK-LABEL: define void @diamondWithConstantVector(
|
|
; CHECK-SAME: ptr [[PTR:%.*]]) {
|
|
; CHECK-NEXT: [[GEPA0:%.*]] = getelementptr i32, ptr [[PTR]], i64 0
|
|
; CHECK-NEXT: [[GEPB0:%.*]] = getelementptr i32, ptr [[PTR]], i64 10
|
|
; CHECK-NEXT: store <2 x i32> zeroinitializer, ptr [[GEPA0]], align 4, !sandboxvec [[META14:![0-9]+]]
|
|
; CHECK-NEXT: store <2 x i32> zeroinitializer, ptr [[GEPB0]], align 4, !sandboxvec [[META15:![0-9]+]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; REVERT-LABEL: define void @diamondWithConstantVector(
|
|
; REVERT-SAME: ptr [[PTR:%.*]]) {
|
|
; REVERT-NEXT: [[GEPA0:%.*]] = getelementptr i32, ptr [[PTR]], i64 0
|
|
; REVERT-NEXT: [[GEPA1:%.*]] = getelementptr i32, ptr [[PTR]], i64 1, !sandboxvec [[META14:![0-9]+]]
|
|
; REVERT-NEXT: [[GEPB0:%.*]] = getelementptr i32, ptr [[PTR]], i64 10
|
|
; REVERT-NEXT: [[GEPB1:%.*]] = getelementptr i32, ptr [[PTR]], i64 11, !sandboxvec [[META15:![0-9]+]]
|
|
; REVERT-NEXT: [[ZEXT0:%.*]] = zext i16 0 to i32, !sandboxvec [[META14]]
|
|
; REVERT-NEXT: [[ZEXT1:%.*]] = zext i16 0 to i32, !sandboxvec [[META14]]
|
|
; REVERT-NEXT: store i32 [[ZEXT0]], ptr [[GEPA0]], align 4, !sandboxvec [[META14]]
|
|
; REVERT-NEXT: store i32 [[ZEXT1]], ptr [[GEPA1]], align 4, !sandboxvec [[META14]]
|
|
; REVERT-NEXT: [[ORB0:%.*]] = or i32 0, [[ZEXT0]], !sandboxvec [[META15]]
|
|
; REVERT-NEXT: [[ORB1:%.*]] = or i32 0, [[ZEXT1]], !sandboxvec [[META15]]
|
|
; REVERT-NEXT: store i32 [[ORB0]], ptr [[GEPB0]], align 4, !sandboxvec [[META15]]
|
|
; REVERT-NEXT: store i32 [[ORB1]], ptr [[GEPB1]], align 4, !sandboxvec [[META15]]
|
|
; REVERT-NEXT: ret void
|
|
;
|
|
%gepA0 = getelementptr i32, ptr %ptr, i64 0
|
|
%gepA1 = getelementptr i32, ptr %ptr, i64 1
|
|
|
|
%gepB0 = getelementptr i32, ptr %ptr, i64 10
|
|
%gepB1 = getelementptr i32, ptr %ptr, i64 11
|
|
|
|
%zext0 = zext i16 0 to i32
|
|
%zext1 = zext i16 0 to i32
|
|
|
|
store i32 %zext0, ptr %gepA0
|
|
store i32 %zext1, ptr %gepA1
|
|
|
|
%orB0 = or i32 0, %zext0
|
|
%orB1 = or i32 0, %zext1
|
|
store i32 %orB0, ptr %gepB0
|
|
store i32 %orB1, ptr %gepB1
|
|
ret void
|
|
}
|
|
|
|
; Check that we don't get def-after-use errors due to wrong placement
|
|
; of new vector instructions.
|
|
define void @vecInstrsPlacement(ptr %ptr0) {
|
|
; CHECK-LABEL: define void @vecInstrsPlacement(
|
|
; CHECK-SAME: ptr [[PTR0:%.*]]) {
|
|
; CHECK-NEXT: [[VECL:%.*]] = load <2 x double>, ptr [[PTR0]], align 8, !sandboxvec [[META16:![0-9]+]]
|
|
; CHECK-NEXT: [[VECL1:%.*]] = load <2 x double>, ptr [[PTR0]], align 8, !sandboxvec [[META16]]
|
|
; CHECK-NEXT: [[VEC2:%.*]] = fmul <2 x double> [[VECL]], [[VECL1]], !sandboxvec [[META16]]
|
|
; CHECK-NEXT: [[VEC:%.*]] = fmul <2 x double> [[VECL]], [[VECL1]], !sandboxvec [[META16]]
|
|
; CHECK-NEXT: [[VEC3:%.*]] = fadd <2 x double> [[VEC]], [[VEC2]], !sandboxvec [[META16]]
|
|
; CHECK-NEXT: store <2 x double> [[VEC3]], ptr [[PTR0]], align 8, !sandboxvec [[META16]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; REVERT-LABEL: define void @vecInstrsPlacement(
|
|
; REVERT-SAME: ptr [[PTR0:%.*]]) {
|
|
; REVERT-NEXT: [[PTR1:%.*]] = getelementptr inbounds double, ptr [[PTR0]], i64 1, !sandboxvec [[META16:![0-9]+]]
|
|
; REVERT-NEXT: [[LDA_0:%.*]] = load double, ptr [[PTR0]], align 8, !sandboxvec [[META16]]
|
|
; REVERT-NEXT: [[LDA_1:%.*]] = load double, ptr [[PTR1]], align 8, !sandboxvec [[META16]]
|
|
; REVERT-NEXT: [[LDB_0:%.*]] = load double, ptr [[PTR0]], align 8, !sandboxvec [[META16]]
|
|
; REVERT-NEXT: [[LDB_1:%.*]] = load double, ptr [[PTR1]], align 8, !sandboxvec [[META16]]
|
|
; REVERT-NEXT: [[MUL0:%.*]] = fmul double [[LDA_0]], [[LDB_0]], !sandboxvec [[META16]]
|
|
; REVERT-NEXT: [[MUL1:%.*]] = fmul double [[LDA_1]], [[LDB_1]], !sandboxvec [[META16]]
|
|
; REVERT-NEXT: [[MUL2:%.*]] = fmul double [[LDA_0]], [[LDB_0]], !sandboxvec [[META16]]
|
|
; REVERT-NEXT: [[MUL3:%.*]] = fmul double [[LDA_1]], [[LDB_1]], !sandboxvec [[META16]]
|
|
; REVERT-NEXT: [[ADD0:%.*]] = fadd double [[MUL0]], [[MUL2]], !sandboxvec [[META16]]
|
|
; REVERT-NEXT: [[ADD1:%.*]] = fadd double [[MUL1]], [[MUL3]], !sandboxvec [[META16]]
|
|
; REVERT-NEXT: store double [[ADD0]], ptr [[PTR0]], align 8, !sandboxvec [[META16]]
|
|
; REVERT-NEXT: store double [[ADD1]], ptr [[PTR1]], align 8, !sandboxvec [[META16]]
|
|
; REVERT-NEXT: ret void
|
|
;
|
|
%ptr1 = getelementptr inbounds double, ptr %ptr0, i64 1
|
|
%ldA_0 = load double, ptr %ptr0
|
|
%ldA_1 = load double, ptr %ptr1
|
|
|
|
%ldB_0 = load double, ptr %ptr0
|
|
%ldB_1 = load double, ptr %ptr1
|
|
|
|
%mul0 = fmul double %ldA_0, %ldB_0
|
|
%mul1 = fmul double %ldA_1, %ldB_1
|
|
|
|
%mul2 = fmul double %ldA_0, %ldB_0
|
|
%mul3 = fmul double %ldA_1, %ldB_1
|
|
|
|
%add0 = fadd double %mul0, %mul2
|
|
%add1 = fadd double %mul1, %mul3
|
|
|
|
store double %add0, ptr %ptr0
|
|
store double %add1, ptr %ptr1
|
|
ret void
|
|
}
|
|
|
|
; During the bottom-up traversal we form bundle {ldA0,ldA1} but later when we
|
|
; visit the RHS operands of the additions we try to form {ldA1,ldA2}
|
|
; which is not allowed.
|
|
define void @instrsInMultipleBundles(ptr noalias %ptr) {
|
|
; CHECK-LABEL: define void @instrsInMultipleBundles(
|
|
; CHECK-SAME: ptr noalias [[PTR:%.*]]) {
|
|
; CHECK-NEXT: [[GEP0:%.*]] = getelementptr i8, ptr [[PTR]], i64 0
|
|
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 2
|
|
; CHECK-NEXT: [[LDA2:%.*]] = load i8, ptr [[GEP2]], align 1
|
|
; CHECK-NEXT: [[VECL:%.*]] = load <2 x i8>, ptr [[GEP0]], align 1, !sandboxvec [[META17:![0-9]+]]
|
|
; CHECK-NEXT: [[VEXT:%.*]] = extractelement <2 x i8> [[VECL]], i32 1, !sandboxvec [[META17]]
|
|
; CHECK-NEXT: [[VINS:%.*]] = insertelement <2 x i8> poison, i8 [[VEXT]], i32 0, !sandboxvec [[META17]]
|
|
; CHECK-NEXT: [[VINS1:%.*]] = insertelement <2 x i8> [[VINS]], i8 [[LDA2]], i32 1, !sandboxvec [[META17]]
|
|
; CHECK-NEXT: [[VEC:%.*]] = add <2 x i8> [[VECL]], [[VINS1]], !sandboxvec [[META17]]
|
|
; CHECK-NEXT: store <2 x i8> [[VEC]], ptr [[GEP0]], align 1, !sandboxvec [[META17]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; REVERT-LABEL: define void @instrsInMultipleBundles(
|
|
; REVERT-SAME: ptr noalias [[PTR:%.*]]) {
|
|
; REVERT-NEXT: [[GEP0:%.*]] = getelementptr i8, ptr [[PTR]], i64 0
|
|
; REVERT-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[PTR]], i64 1, !sandboxvec [[META17:![0-9]+]]
|
|
; REVERT-NEXT: [[GEP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 2
|
|
; REVERT-NEXT: [[LDA0:%.*]] = load i8, ptr [[GEP0]], align 1, !sandboxvec [[META17]]
|
|
; REVERT-NEXT: [[LDA1:%.*]] = load i8, ptr [[GEP1]], align 1, !sandboxvec [[META17]]
|
|
; REVERT-NEXT: [[LDA2:%.*]] = load i8, ptr [[GEP2]], align 1
|
|
; REVERT-NEXT: [[ADD0:%.*]] = add i8 [[LDA0]], [[LDA1]], !sandboxvec [[META17]]
|
|
; REVERT-NEXT: [[ADD1:%.*]] = add i8 [[LDA1]], [[LDA2]], !sandboxvec [[META17]]
|
|
; REVERT-NEXT: store i8 [[ADD0]], ptr [[GEP0]], align 1, !sandboxvec [[META17]]
|
|
; REVERT-NEXT: store i8 [[ADD1]], ptr [[GEP1]], align 1, !sandboxvec [[META17]]
|
|
; REVERT-NEXT: ret void
|
|
;
|
|
%gep0 = getelementptr i8, ptr %ptr, i64 0
|
|
%gep1 = getelementptr i8, ptr %ptr, i64 1
|
|
%gep2 = getelementptr i8, ptr %ptr, i64 2
|
|
%ldA0 = load i8, ptr %gep0
|
|
%ldA1 = load i8, ptr %gep1
|
|
%ldA2 = load i8, ptr %gep2
|
|
%add0 = add i8 %ldA0, %ldA1
|
|
%add1 = add i8 %ldA1, %ldA2
|
|
store i8 %add0, ptr %gep0
|
|
store i8 %add1, ptr %gep1
|
|
ret void
|
|
}
|
|
|
|
define void @vectorize_constants(ptr %ptr) {
|
|
; CHECK-LABEL: define void @vectorize_constants(
|
|
; CHECK-SAME: ptr [[PTR:%.*]]) {
|
|
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr i8, ptr [[PTR]], i32 0
|
|
; CHECK-NEXT: [[VECL:%.*]] = load <2 x i8>, ptr [[PTR0]], align 1, !sandboxvec [[META18:![0-9]+]]
|
|
; CHECK-NEXT: [[VEC:%.*]] = add <2 x i8> [[VECL]], <i8 0, i8 1>, !sandboxvec [[META18]]
|
|
; CHECK-NEXT: store <2 x i8> [[VEC]], ptr [[PTR0]], align 1, !sandboxvec [[META18]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; REVERT-LABEL: define void @vectorize_constants(
|
|
; REVERT-SAME: ptr [[PTR:%.*]]) {
|
|
; REVERT-NEXT: [[PTR0:%.*]] = getelementptr i8, ptr [[PTR]], i32 0
|
|
; REVERT-NEXT: [[PTR1:%.*]] = getelementptr i8, ptr [[PTR]], i32 1, !sandboxvec [[META18:![0-9]+]]
|
|
; REVERT-NEXT: [[LD0:%.*]] = load i8, ptr [[PTR0]], align 1, !sandboxvec [[META18]]
|
|
; REVERT-NEXT: [[LD1:%.*]] = load i8, ptr [[PTR1]], align 1, !sandboxvec [[META18]]
|
|
; REVERT-NEXT: [[ADD0:%.*]] = add i8 [[LD0]], 0, !sandboxvec [[META18]]
|
|
; REVERT-NEXT: [[ADD1:%.*]] = add i8 [[LD1]], 1, !sandboxvec [[META18]]
|
|
; REVERT-NEXT: store i8 [[ADD0]], ptr [[PTR0]], align 1, !sandboxvec [[META18]]
|
|
; REVERT-NEXT: store i8 [[ADD1]], ptr [[PTR1]], align 1, !sandboxvec [[META18]]
|
|
; REVERT-NEXT: ret void
|
|
;
|
|
%ptr0 = getelementptr i8, ptr %ptr, i32 0
|
|
%ptr1 = getelementptr i8, ptr %ptr, i32 1
|
|
%ld0 = load i8, ptr %ptr0
|
|
%ld1 = load i8, ptr %ptr1
|
|
%add0 = add i8 %ld0, 0
|
|
%add1 = add i8 %ld1, 1
|
|
store i8 %add0, ptr %ptr0
|
|
store i8 %add1, ptr %ptr1
|
|
ret void
|
|
}
|
|
|
|
define void @vectorize_constant_vectors(ptr %ptr) {
|
|
; CHECK-LABEL: define void @vectorize_constant_vectors(
|
|
; CHECK-SAME: ptr [[PTR:%.*]]) {
|
|
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr <2 x i8>, ptr [[PTR]], i32 0
|
|
; CHECK-NEXT: [[VECL:%.*]] = load <4 x i8>, ptr [[PTR0]], align 2, !sandboxvec [[META19:![0-9]+]]
|
|
; CHECK-NEXT: [[VEC:%.*]] = sub <4 x i8> [[VECL]], <i8 0, i8 0, i8 1, i8 1>, !sandboxvec [[META19]]
|
|
; CHECK-NEXT: store <4 x i8> [[VEC]], ptr [[PTR0]], align 2, !sandboxvec [[META19]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; REVERT-LABEL: define void @vectorize_constant_vectors(
|
|
; REVERT-SAME: ptr [[PTR:%.*]]) {
|
|
; REVERT-NEXT: [[PTR0:%.*]] = getelementptr <2 x i8>, ptr [[PTR]], i32 0
|
|
; REVERT-NEXT: [[PTR1:%.*]] = getelementptr <2 x i8>, ptr [[PTR]], i32 1, !sandboxvec [[META19:![0-9]+]]
|
|
; REVERT-NEXT: [[LD0:%.*]] = load <2 x i8>, ptr [[PTR0]], align 2, !sandboxvec [[META19]]
|
|
; REVERT-NEXT: [[LD1:%.*]] = load <2 x i8>, ptr [[PTR1]], align 2, !sandboxvec [[META19]]
|
|
; REVERT-NEXT: [[SUB0:%.*]] = sub <2 x i8> [[LD0]], zeroinitializer, !sandboxvec [[META19]]
|
|
; REVERT-NEXT: [[SUB1:%.*]] = sub <2 x i8> [[LD1]], splat (i8 1), !sandboxvec [[META19]]
|
|
; REVERT-NEXT: store <2 x i8> [[SUB0]], ptr [[PTR0]], align 2, !sandboxvec [[META19]]
|
|
; REVERT-NEXT: store <2 x i8> [[SUB1]], ptr [[PTR1]], align 2, !sandboxvec [[META19]]
|
|
; REVERT-NEXT: ret void
|
|
;
|
|
%ptr0 = getelementptr <2 x i8>, ptr %ptr, i32 0
|
|
%ptr1 = getelementptr <2 x i8>, ptr %ptr, i32 1
|
|
%ld0 = load <2 x i8>, ptr %ptr0
|
|
%ld1 = load <2 x i8>, ptr %ptr1
|
|
%sub0 = sub <2 x i8> %ld0, splat(i8 0)
|
|
%sub1 = sub <2 x i8> %ld1, splat(i8 1)
|
|
store <2 x i8> %sub0, ptr %ptr0
|
|
store <2 x i8> %sub1, ptr %ptr1
|
|
ret void
|
|
}
|
|
|
|
; ZExt's operands can be of different types.
|
|
define void @diff_types(ptr %ptr, ptr %ptrX, ptr %ptrY) {
|
|
; CHECK-LABEL: define void @diff_types(
|
|
; CHECK-SAME: ptr [[PTR:%.*]], ptr [[PTRX:%.*]], ptr [[PTRY:%.*]]) {
|
|
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; CHECK-NEXT: [[LDX:%.*]] = load i16, ptr [[PTRX]], align 2
|
|
; CHECK-NEXT: [[LDY:%.*]] = load i8, ptr [[PTRY]], align 1
|
|
; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i16 [[LDX]], 0
|
|
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[LDY]], 0
|
|
; CHECK-NEXT: [[PACK:%.*]] = insertelement <2 x i1> poison, i1 [[CMP0]], i32 0, !sandboxvec [[META20:![0-9]+]]
|
|
; CHECK-NEXT: [[PACK1:%.*]] = insertelement <2 x i1> [[PACK]], i1 [[CMP1]], i32 1, !sandboxvec [[META20]]
|
|
; CHECK-NEXT: [[VCAST:%.*]] = zext <2 x i1> [[PACK1]] to <2 x i32>, !sandboxvec [[META20]]
|
|
; CHECK-NEXT: store <2 x i32> [[VCAST]], ptr [[PTR0]], align 4, !sandboxvec [[META20]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; REVERT-LABEL: define void @diff_types(
|
|
; REVERT-SAME: ptr [[PTR:%.*]], ptr [[PTRX:%.*]], ptr [[PTRY:%.*]]) {
|
|
; REVERT-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
|
|
; REVERT-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1, !sandboxvec [[META20:![0-9]+]]
|
|
; REVERT-NEXT: [[LDX:%.*]] = load i16, ptr [[PTRX]], align 2
|
|
; REVERT-NEXT: [[LDY:%.*]] = load i8, ptr [[PTRY]], align 1
|
|
; REVERT-NEXT: [[CMP0:%.*]] = icmp eq i16 [[LDX]], 0
|
|
; REVERT-NEXT: [[CMP1:%.*]] = icmp eq i8 [[LDY]], 0
|
|
; REVERT-NEXT: [[ZEXT0:%.*]] = zext i1 [[CMP0]] to i32, !sandboxvec [[META20]]
|
|
; REVERT-NEXT: [[ZEXT1:%.*]] = zext i1 [[CMP1]] to i32, !sandboxvec [[META20]]
|
|
; REVERT-NEXT: store i32 [[ZEXT0]], ptr [[PTR0]], align 4, !sandboxvec [[META20]]
|
|
; REVERT-NEXT: store i32 [[ZEXT1]], ptr [[PTR1]], align 4, !sandboxvec [[META20]]
|
|
; REVERT-NEXT: ret void
|
|
;
|
|
%ptr0 = getelementptr float, ptr %ptr, i32 0
|
|
%ptr1 = getelementptr float, ptr %ptr, i32 1
|
|
|
|
%ldX = load i16, ptr %ptrX
|
|
%ldY = load i8, ptr %ptrY
|
|
%cmp0 = icmp eq i16 %ldX, 0
|
|
%cmp1 = icmp eq i8 %ldY, 0
|
|
%zext0 = zext i1 %cmp0 to i32
|
|
%zext1 = zext i1 %cmp1 to i32
|
|
store i32 %zext0, ptr %ptr0
|
|
store i32 %zext1, ptr %ptr1
|
|
|
|
ret void
|
|
}
|
|
|
|
;.
|
|
; CHECK: [[META0]] = distinct !{!"sandboxregion"}
|
|
; CHECK: [[META1]] = distinct !{!"sandboxregion"}
|
|
; CHECK: [[META2]] = distinct !{!"sandboxregion"}
|
|
; CHECK: [[META3]] = distinct !{!"sandboxregion"}
|
|
; CHECK: [[META4]] = distinct !{!"sandboxregion"}
|
|
; CHECK: [[META5]] = distinct !{!"sandboxregion"}
|
|
; CHECK: [[META6]] = distinct !{!"sandboxregion"}
|
|
; CHECK: [[META7]] = distinct !{!"sandboxregion"}
|
|
; CHECK: [[META8]] = distinct !{!"sandboxregion"}
|
|
; CHECK: [[META9]] = distinct !{!"sandboxregion"}
|
|
; CHECK: [[META10]] = distinct !{!"sandboxregion"}
|
|
; CHECK: [[META11]] = distinct !{!"sandboxregion"}
|
|
; CHECK: [[META12]] = distinct !{!"sandboxregion"}
|
|
; CHECK: [[META13]] = distinct !{!"sandboxregion"}
|
|
; CHECK: [[META14]] = distinct !{!"sandboxregion"}
|
|
; CHECK: [[META15]] = distinct !{!"sandboxregion"}
|
|
; CHECK: [[META16]] = distinct !{!"sandboxregion"}
|
|
; CHECK: [[META17]] = distinct !{!"sandboxregion"}
|
|
; CHECK: [[META18]] = distinct !{!"sandboxregion"}
|
|
; CHECK: [[META19]] = distinct !{!"sandboxregion"}
|
|
; CHECK: [[META20]] = distinct !{!"sandboxregion"}
|
|
;.
|
|
; REVERT: [[META0]] = distinct !{!"sandboxregion"}
|
|
; REVERT: [[META1]] = distinct !{!"sandboxregion"}
|
|
; REVERT: [[META2]] = distinct !{!"sandboxregion"}
|
|
; REVERT: [[META3]] = distinct !{!"sandboxregion"}
|
|
; REVERT: [[META4]] = distinct !{!"sandboxregion"}
|
|
; REVERT: [[META5]] = distinct !{!"sandboxregion"}
|
|
; REVERT: [[META6]] = distinct !{!"sandboxregion"}
|
|
; REVERT: [[META7]] = distinct !{!"sandboxregion"}
|
|
; REVERT: [[META8]] = distinct !{!"sandboxregion"}
|
|
; REVERT: [[META9]] = distinct !{!"sandboxregion"}
|
|
; REVERT: [[META10]] = distinct !{!"sandboxregion"}
|
|
; REVERT: [[META11]] = distinct !{!"sandboxregion"}
|
|
; REVERT: [[META12]] = distinct !{!"sandboxregion"}
|
|
; REVERT: [[META13]] = distinct !{!"sandboxregion"}
|
|
; REVERT: [[META14]] = distinct !{!"sandboxregion"}
|
|
; REVERT: [[META15]] = distinct !{!"sandboxregion"}
|
|
; REVERT: [[META16]] = distinct !{!"sandboxregion"}
|
|
; REVERT: [[META17]] = distinct !{!"sandboxregion"}
|
|
; REVERT: [[META18]] = distinct !{!"sandboxregion"}
|
|
; REVERT: [[META19]] = distinct !{!"sandboxregion"}
|
|
; REVERT: [[META20]] = distinct !{!"sandboxregion"}
|
|
;.
|