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.
80 lines
4.0 KiB
LLVM
80 lines
4.0 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
|
|
|
|
; This used to crash because the newly added pack instructions would not update
|
|
; the DAG and scheduler, leading to def-after-use.
|
|
define void @check_dag_scheduler_update(ptr noalias %p, ptr noalias %p1) {
|
|
; CHECK-LABEL: define void @check_dag_scheduler_update(
|
|
; CHECK-SAME: ptr noalias [[P:%.*]], ptr noalias [[P1:%.*]]) {
|
|
; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[P]], align 4
|
|
; CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr i32, ptr [[P]], i64 32
|
|
; CHECK-NEXT: [[I2:%.*]] = load i32, ptr [[ARRAYIDX4]], align 4
|
|
; CHECK-NEXT: [[ARRAYIDX11:%.*]] = getelementptr i32, ptr [[P]], i64 33
|
|
; CHECK-NEXT: [[I4:%.*]] = load i32, ptr [[ARRAYIDX11]], align 4
|
|
; CHECK-NEXT: [[ARRAYIDX18:%.*]] = getelementptr i32, ptr [[P]], i64 34
|
|
; CHECK-NEXT: [[I6:%.*]] = load i32, ptr [[ARRAYIDX18]], align 4
|
|
; CHECK-NEXT: [[PACK:%.*]] = insertelement <4 x i32> poison, i32 [[I]], i32 0, !sandboxvec [[META0:![0-9]+]]
|
|
; CHECK-NEXT: [[PACK1:%.*]] = insertelement <4 x i32> [[PACK]], i32 [[I2]], i32 1, !sandboxvec [[META0]]
|
|
; CHECK-NEXT: [[PACK2:%.*]] = insertelement <4 x i32> [[PACK1]], i32 [[I4]], i32 2, !sandboxvec [[META0]]
|
|
; CHECK-NEXT: [[PACK3:%.*]] = insertelement <4 x i32> [[PACK2]], i32 [[I6]], i32 3, !sandboxvec [[META0]]
|
|
; CHECK-NEXT: [[VECL:%.*]] = load <4 x i32>, ptr [[P]], align 4, !sandboxvec [[META0]]
|
|
; CHECK-NEXT: [[VEC:%.*]] = add nsw <4 x i32> [[PACK3]], [[VECL]], !sandboxvec [[META0]]
|
|
; CHECK-NEXT: store <4 x i32> [[VEC]], ptr [[P1]], align 4, !sandboxvec [[META0]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%i = load i32, ptr %p
|
|
%i1 = load i32, ptr %p
|
|
%add = add nsw i32 %i, %i1
|
|
store i32 %add, ptr %p1
|
|
%arrayidx4 = getelementptr i32, ptr %p, i64 32
|
|
%i2 = load i32, ptr %arrayidx4
|
|
%arrayidx6 = getelementptr i32, ptr %p, i64 1
|
|
%i3 = load i32, ptr %arrayidx6
|
|
%add7 = add nsw i32 %i2, %i3
|
|
%arrayidx9 = getelementptr i32, ptr %p1, i64 1
|
|
store i32 %add7, ptr %arrayidx9
|
|
%arrayidx11 = getelementptr i32, ptr %p, i64 33
|
|
%i4 = load i32, ptr %arrayidx11
|
|
%arrayidx13 = getelementptr i32, ptr %p, i64 2
|
|
%i5 = load i32, ptr %arrayidx13
|
|
%add14 = add nsw i32 %i4, %i5
|
|
%arrayidx16 = getelementptr i32, ptr %p1, i64 2
|
|
store i32 %add14, ptr %arrayidx16
|
|
%arrayidx18 = getelementptr i32, ptr %p, i64 34
|
|
%i6 = load i32, ptr %arrayidx18
|
|
%arrayidx19 = getelementptr i32, ptr %p, i64 3
|
|
%i7 = load i32, ptr %arrayidx19
|
|
%add21 = add nsw i32 %i6, %i7
|
|
%arrayidx23 = getelementptr i32, ptr %p1, i64 3
|
|
store i32 %add21, ptr %arrayidx23
|
|
ret void
|
|
}
|
|
|
|
; This used to generate use-before-def because of a buggy update of the
|
|
; top-of-schedule variable.
|
|
define <4 x float> @check_top_of_schedule(ptr %0) {
|
|
; CHECK-LABEL: define <4 x float> @check_top_of_schedule(
|
|
; CHECK-SAME: ptr [[TMP0:%.*]]) {
|
|
; CHECK-NEXT: [[INS_1:%.*]] = insertelement <4 x float> zeroinitializer, float poison, i64 0
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr double, ptr [[TMP0]], i64 1
|
|
; CHECK-NEXT: [[INS_2:%.*]] = insertelement <4 x float> [[INS_1]], float 0.000000e+00, i64 0
|
|
; CHECK-NEXT: store <2 x double> <double 0.000000e+00, double 1.000000e+00>, ptr [[GEP_1]], align 8, !sandboxvec [[META1:![0-9]+]]
|
|
; CHECK-NEXT: ret <4 x float> [[INS_2]]
|
|
;
|
|
%trunc.1 = fptrunc double 0.000000e+00 to float
|
|
%trunc.2 = fptrunc double 1.000000e+00 to float
|
|
%ins.1 = insertelement <4 x float> zeroinitializer, float poison, i64 0
|
|
%ins.2 = insertelement <4 x float> %ins.1, float %trunc.1, i64 0
|
|
%ext.1 = fpext float %trunc.1 to double
|
|
%gep.1 = getelementptr double, ptr %0, i64 1
|
|
store double %ext.1, ptr %gep.1, align 8
|
|
%ext.2 = fpext float %trunc.2 to double
|
|
%gep.2 = getelementptr double, ptr %0, i64 2
|
|
store double %ext.2, ptr %gep.2, align 8
|
|
ret <4 x float> %ins.2
|
|
}
|
|
;.
|
|
; CHECK: [[META0]] = distinct !{!"sandboxregion"}
|
|
; CHECK: [[META1]] = distinct !{!"sandboxregion"}
|
|
;.
|