| ; 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 |
| ; CHECK-NEXT: [[PACK1:%.*]] = insertelement <4 x i32> [[PACK]], i32 [[I2]], i32 1 |
| ; CHECK-NEXT: [[PACK2:%.*]] = insertelement <4 x i32> [[PACK1]], i32 [[I4]], i32 2 |
| ; CHECK-NEXT: [[PACK3:%.*]] = insertelement <4 x i32> [[PACK2]], i32 [[I6]], i32 3 |
| ; CHECK-NEXT: [[VECL:%.*]] = load <4 x i32>, ptr [[P]], align 4 |
| ; CHECK-NEXT: [[VEC:%.*]] = add nsw <4 x i32> [[PACK3]], [[VECL]] |
| ; CHECK-NEXT: store <4 x i32> [[VEC]], ptr [[P1]], align 4 |
| ; 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: [[TRUNC_1:%.*]] = fptrunc double 0.000000e+00 to float |
| ; CHECK-NEXT: [[INS_2:%.*]] = insertelement <4 x float> [[INS_1]], float [[TRUNC_1]], i64 0 |
| ; CHECK-NEXT: store <2 x double> <double 0.000000e+00, double 1.000000e+00>, ptr [[GEP_1]], align 8 |
| ; 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 |
| } |