diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -2114,6 +2114,8 @@ // Read/modify/write the vector, inserting the new element. llvm::Value *Vec = Builder.CreateLoad(Dst.getVectorAddress(), Dst.isVolatileQualified()); + applyNoundefToLoadInst(CGM.getCodeGenOpts().EnableNoundefLoadAttr, + Dst.getType(), dyn_cast(Vec)); auto *IRStoreTy = dyn_cast(Vec->getType()); if (IRStoreTy) { auto *IRVecTy = llvm::FixedVectorType::get( @@ -2147,7 +2149,9 @@ llvm::MatrixBuilder MB(Builder); MB.CreateIndexAssumption(Idx, MatTy->getNumElementsFlattened()); } - llvm::Instruction *Load = Builder.CreateLoad(Dst.getMatrixAddress()); + llvm::LoadInst *Load = Builder.CreateLoad(Dst.getMatrixAddress()); + applyNoundefToLoadInst(CGM.getCodeGenOpts().EnableNoundefLoadAttr, + Dst.getType(), Load); llvm::Value *Vec = Builder.CreateInsertElement(Load, Src.getScalarVal(), Idx, "matins"); Builder.CreateStore(Vec, Dst.getMatrixAddress(), @@ -2315,6 +2319,8 @@ // value now. llvm::Value *Vec = Builder.CreateLoad(Dst.getExtVectorAddress(), Dst.isVolatileQualified()); + applyNoundefToLoadInst(CGM.getCodeGenOpts().EnableNoundefLoadAttr, + Dst.getType(), dyn_cast(Vec)); const llvm::Constant *Elts = Dst.getExtVectorElts(); llvm::Value *SrcVal = Src.getScalarVal(); diff --git a/clang/test/CodeGen/matrix-type-operators.c b/clang/test/CodeGen/matrix-type-operators.c --- a/clang/test/CodeGen/matrix-type-operators.c +++ b/clang/test/CodeGen/matrix-type-operators.c @@ -965,7 +965,7 @@ // CHECK-LABEL: @insert_double_matrix_const_idx_ll_u_double( // NOOPT: [[D:%.*]] = load double, double* %d.addr, align 8, !noundef [[NOUNDEF]]{{$}} // OPT: [[D:%.*]] = load double, double* %d.addr, align 8, !tbaa !{{[0-9]+}}, !noundef [[NOUNDEF]]{{$}} - // CHECK-NEXT: [[MAT:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8{{$}} + // CHECK-NEXT: [[MAT:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8, !noundef [[NOUNDEF:![0-9]+]]{{$}} // CHECK-NEXT: [[MATINS:%.*]] = insertelement <25 x double> [[MAT]], double [[D]], i64 5 // CHECK-NEXT: store <25 x double> [[MATINS]], <25 x double>* {{.*}}, align 8 // CHECK-NEXT: ret void @@ -977,7 +977,7 @@ // CHECK-LABEL: @insert_double_matrix_const_idx_i_u_double( // NOOPT: [[D:%.*]] = load double, double* %d.addr, align 8, !noundef [[NOUNDEF]]{{$}} // OPT: [[D:%.*]] = load double, double* %d.addr, align 8, !tbaa !{{[0-9]+}}, !noundef [[NOUNDEF]]{{$}} - // CHECK-NEXT: [[MAT:%.*]] = load <25 x double>, <25 x double>* [[MAT_ADDR:%.*]], align 8{{$}} + // CHECK-NEXT: [[MAT:%.*]] = load <25 x double>, <25 x double>* [[MAT_ADDR:%.*]], align 8, !noundef [[NOUNDEF]]{{$}} // CHECK-NEXT: [[MATINS:%.*]] = insertelement <25 x double> [[MAT]], double [[D]], i64 21 // CHECK-NEXT: store <25 x double> [[MATINS]], <25 x double>* [[MAT_ADDR]], align 8 // CHECK-NEXT: ret void @@ -989,7 +989,7 @@ // CHECK-LABEL: @insert_float_matrix_const_idx_ull_i_float( // NOOPT: [[E:%.*]] = load float, float* %e.addr, align 4, !noundef [[NOUNDEF]]{{$}} // OPT: [[E:%.*]] = load float, float* %e.addr, align 4, !tbaa !{{[0-9]+}}, !noundef [[NOUNDEF]]{{$}} - // CHECK-NEXT: [[MAT:%.*]] = load <6 x float>, <6 x float>* [[MAT_ADDR:%.*]], align 4{{$}} + // CHECK-NEXT: [[MAT:%.*]] = load <6 x float>, <6 x float>* [[MAT_ADDR:%.*]], align 4, !noundef [[NOUNDEF]]{{$}} // CHECK-NEXT: [[MATINS:%.*]] = insertelement <6 x float> [[MAT]], float [[E]], i64 3 // CHECK-NEXT: store <6 x float> [[MATINS]], <6 x float>* [[MAT_ADDR]], align 4 // CHECK-NEXT: ret void @@ -1011,7 +1011,7 @@ // CHECK-NEXT: [[IDX2:%.*]] = add i64 [[IDX1]], [[J_EXT]] // OPT-NEXT: [[CMP:%.*]] = icmp ult i64 [[IDX2]], 6 // OPT-NEXT: call void @llvm.assume(i1 [[CMP]]) - // CHECK-NEXT: [[MAT:%.*]] = load <6 x float>, <6 x float>* [[MAT_ADDR:%.*]], align 4{{$}} + // CHECK-NEXT: [[MAT:%.*]] = load <6 x float>, <6 x float>* [[MAT_ADDR:%.*]], align 4, !noundef [[NOUNDEF]]{{$}} // CHECK-NEXT: [[MATINS:%.*]] = insertelement <6 x float> [[MAT]], float [[E]], i64 [[IDX2]] // CHECK-NEXT: store <6 x float> [[MATINS]], <6 x float>* [[MAT_ADDR]], align 4 // CHECK-NEXT: ret void @@ -1032,7 +1032,7 @@ // CHECK-NEXT: [[IDX2:%.*]] = add i64 [[IDX1]], [[J_EXT]] // OPT-NEXT: [[CMP:%.*]] = icmp ult i64 [[IDX2]], 6 // OPT-NEXT: call void @llvm.assume(i1 [[CMP]]) - // CHECK-NEXT: [[MAT:%.*]] = load <6 x float>, <6 x float>* [[MAT_ADDR:%.*]], align 4{{$}} + // CHECK-NEXT: [[MAT:%.*]] = load <6 x float>, <6 x float>* [[MAT_ADDR:%.*]], align 4, !noundef [[NOUNDEF]]{{$}} // CHECK-NEXT: [[MATINS:%.*]] = insertelement <6 x float> [[MAT]], float [[E]], i64 [[IDX2]] // CHECK-NEXT: store <6 x float> [[MATINS]], <6 x float>* [[MAT_ADDR]], align 4 // CHECK-NEXT: ret void @@ -1053,7 +1053,7 @@ // CHECK-NEXT: [[IDX2:%.*]] = add i64 18, [[ADD_EXT]] // OPT-NEXT: [[CMP:%.*]] = icmp ult i64 [[IDX2]], 27 // OPT-NEXT: call void @llvm.assume(i1 [[CMP]]) - // CHECK-NEXT: [[MAT:%.*]] = load <27 x i32>, <27 x i32>* [[MAT_ADDR:%.*]], align 4{{$}} + // CHECK-NEXT: [[MAT:%.*]] = load <27 x i32>, <27 x i32>* [[MAT_ADDR:%.*]], align 4, !noundef [[NOUNDEF]]{{$}} // CHECK-NEXT: [[MATINS:%.*]] = insertelement <27 x i32> [[MAT]], i32 [[I1]], i64 [[IDX2]] // CHECK-NEXT: store <27 x i32> [[MATINS]], <27 x i32>* [[MAT_ADDR]], align 4 // CHECK-NEXT: ret void @@ -1071,7 +1071,7 @@ // NOOPT-NEXT: [[MAT_ADDR1:%.*]] = load [27 x i32]*, [27 x i32]** %a.addr, align 8, !noundef [[NOUNDEF]]{{$}} // OPT-NEXT: [[MAT_ADDR1:%.*]] = load [27 x i32]*, [27 x i32]** %a.addr, align 8, !tbaa !{{[0-9]+}}, !noundef [[NOUNDEF]]{{$}} // CHECK-NEXT: [[MAT_ADDR2:%.*]] = bitcast [27 x i32]* [[MAT_ADDR1]] to <27 x i32>* - // CHECK-NEXT: [[MAT:%.*]] = load <27 x i32>, <27 x i32>* [[MAT_ADDR2]], align 4{{$}} + // CHECK-NEXT: [[MAT:%.*]] = load <27 x i32>, <27 x i32>* [[MAT_ADDR2]], align 4, !noundef [[NOUNDEF]]{{$}} // CHECK-NEXT: [[MATINS:%.*]] = insertelement <27 x i32> [[MAT]], i32 [[I]], i64 13 // CHECK-NEXT: store <27 x i32> [[MATINS]], <27 x i32>* [[MAT_ADDR2]], align 4 // CHECK-NEXT: ret void @@ -1087,7 +1087,7 @@ // CHECK-LABEL: @insert_matching_dimensions1( // NOOPT: [[I:%.*]] = load double, double* %i.addr, align 8, !noundef [[NOUNDEF]]{{$}} // OPT: [[I:%.*]] = load double, double* %i.addr, align 8, !tbaa !{{[0-9]+}}, !noundef [[NOUNDEF]]{{$}} - // CHECK-NEXT: [[MAT:%.*]] = load <9 x double>, <9 x double>* [[MAT_ADDR:%.*]], align 8{{$}} + // CHECK-NEXT: [[MAT:%.*]] = load <9 x double>, <9 x double>* [[MAT_ADDR:%.*]], align 8, !noundef [[NOUNDEF]]{{$}} // CHECK-NEXT: [[MATINS:%.*]] = insertelement <9 x double> [[MAT]], double [[I]], i64 5 // CHECK-NEXT: store <9 x double> [[MATINS]], <9 x double>* [[MAT_ADDR]], align 8 // CHECK-NEXT: ret void @@ -1099,7 +1099,7 @@ // CHECK-LABEL: @insert_matching_dimensions( // NOOPT: [[E:%.*]] = load float, float* %e.addr, align 4, !noundef [[NOUNDEF]]{{$}} // OPT: [[E:%.*]] = load float, float* %e.addr, align 4, !tbaa !{{[0-9]+}}, !noundef [[NOUNDEF]]{{$}} - // CHECK-NEXT: [[MAT:%.*]] = load <9 x float>, <9 x float>* [[MAT_ADDR:%.*]], align 4{{$}} + // CHECK-NEXT: [[MAT:%.*]] = load <9 x float>, <9 x float>* [[MAT_ADDR:%.*]], align 4, !noundef [[NOUNDEF]]{{$}} // CHECK-NEXT: [[MATINS:%.*]] = insertelement <9 x float> [[MAT]], float [[E]], i64 7 // CHECK-NEXT: store <9 x float> [[MATINS]], <9 x float>* [[MAT_ADDR]], align 4 // CHECK-NEXT: ret void @@ -1207,7 +1207,7 @@ // CHECK-NEXT: [[IDX4:%.*]] = add i64 [[IDX3]], 2 // OPT-NEXT: [[CMP:%.*]] = icmp ult i64 [[IDX4]], 9 // OPT-NEXT: call void @llvm.assume(i1 [[CMP]]) - // CHECK-NEXT: [[MAT2:%.*]] = load <9 x float>, <9 x float>* [[MAT_ADDR]], align 4{{$}} + // CHECK-NEXT: [[MAT2:%.*]] = load <9 x float>, <9 x float>* [[MAT_ADDR]], align 4, !noundef [[NOUNDEF]]{{$}} // CHECK-NEXT: [[MATINS:%.*]] = insertelement <9 x float> [[MAT2]], float [[MATEXT]], i64 [[IDX4]] // CHECK-NEXT: store <9 x float> [[MATINS]], <9 x float>* [[MAT_ADDR]], align 4 // CHECK-NEXT: ret void @@ -1220,7 +1220,7 @@ // CHECK: [[A:%.*]] = load <25 x double>, <25 x double>* [[A_PTR:%.*]], align 8, !noundef [[NOUNDEF:![0-9]+]]{{$}} // CHECK-NEXT: [[EXT:%.*]] = extractelement <25 x double> [[A]], i64 17 // CHECK-NEXT: [[SUB:%.*]] = fsub double [[EXT]], 1.000000e+00 - // CHECK-NEXT: [[A2:%.*]] = load <25 x double>, <25 x double>* [[A_PTR]], align 8{{$}} + // CHECK-NEXT: [[A2:%.*]] = load <25 x double>, <25 x double>* [[A_PTR]], align 8, !noundef [[NOUNDEF]]{{$}} // CHECK-NEXT: [[INS:%.*]] = insertelement <25 x double> [[A2]], double [[SUB]], i64 17 // CHECK-NEXT: store <25 x double> [[INS]], <25 x double>* [[A_PTR]], align 8 // CHECK-NEXT: ret void @@ -1250,7 +1250,7 @@ // CHECK-NEXT: [[SUM:%.*]] = fadd float [[EXT]], {{.*}} // OPT-NEXT: [[CMP:%.*]] = icmp ult i64 [[IDX2]], 6 // OPT-NEXT: call void @llvm.assume(i1 [[CMP]]) - // CHECK-NEXT: [[MAT2:%.*]] = load <6 x float>, <6 x float>* [[MAT_PTR]], align 4{{$}} + // CHECK-NEXT: [[MAT2:%.*]] = load <6 x float>, <6 x float>* [[MAT_PTR]], align 4, !noundef [[NOUNDEF]]{{$}} // CHECK-NEXT: [[INS:%.*]] = insertelement <6 x float> [[MAT2]], float [[SUM]], i64 [[IDX2]] // CHECK-NEXT: store <6 x float> [[INS]], <6 x float>* [[MAT_PTR]], align 4 // CHECK-NEXT: ret void @@ -1293,7 +1293,7 @@ // CHECK-NEXT: [[IDX3_2:%.*]] = add i64 [[IDX3_1]], [[MI1_EXT]] // OPT-NEXT: [[CMP:%.*]] = icmp ult i64 [[IDX3_2]], 25 // OPT-NEXT: call void @llvm.assume(i1 [[CMP]]) - // CHECK-NEXT: [[B:%.*]] = load <25 x double>, <25 x double>* [[B_PTR:%.*]], align 8{{$}} + // CHECK-NEXT: [[B:%.*]] = load <25 x double>, <25 x double>* [[B_PTR:%.*]], align 8, !noundef [[NOUNDEF]]{{$}} // CHECK-NEXT: [[INS:%.*]] = insertelement <25 x double> [[B]], double 1.500000e+00, i64 [[IDX3_2]] // CHECK-NEXT: store <25 x double> [[INS]], <25 x double>* [[B_PTR]], align 8 b[a[i][j]][a[j][i] + 2] = 1.5; diff --git a/clang/test/CodeGen/vector-noundef.c b/clang/test/CodeGen/vector-noundef.c --- a/clang/test/CodeGen/vector-noundef.c +++ b/clang/test/CodeGen/vector-noundef.c @@ -37,7 +37,7 @@ // CHECK-NEXT: [[TMP7:%.*]] = load <4 x float>, <4 x float>* [[__A_ADDR_I]], align 16, !noundef [[NOUNDEF2]] // CHECK-NEXT: [[VECEXT1_I:%.*]] = extractelement <4 x float> [[TMP7]], i32 0 // CHECK-NEXT: [[DIV_I:%.*]] = fdiv float [[VECEXT1_I]], [[VECEXT_I]] -// CHECK-NEXT: [[TMP8:%.*]] = load <4 x float>, <4 x float>* [[__A_ADDR_I]], align 16 +// CHECK-NEXT: [[TMP8:%.*]] = load <4 x float>, <4 x float>* [[__A_ADDR_I]], align 16, !noundef [[NOUNDEF2]] // CHECK-NEXT: [[VECINS_I:%.*]] = insertelement <4 x float> [[TMP8]], float [[DIV_I]], i32 0 // CHECK-NEXT: store <4 x float> [[VECINS_I]], <4 x float>* [[__A_ADDR_I]], align 16 // CHECK-NEXT: [[TMP9:%.*]] = load <4 x float>, <4 x float>* [[__A_ADDR_I]], align 16, !noundef [[NOUNDEF2]] diff --git a/clang/test/CodeGenCXX/matrix-type-operators.cpp b/clang/test/CodeGenCXX/matrix-type-operators.cpp --- a/clang/test/CodeGenCXX/matrix-type-operators.cpp +++ b/clang/test/CodeGenCXX/matrix-type-operators.cpp @@ -239,7 +239,7 @@ // CHECK-NEXT: [[IDX2:%.*]] = add i64 [[IDX1]], [[I_EXT]] // OPT-NEXT: [[CMP:%.*]] = icmp ult i64 [[IDX2]], 4 // OPT-NEXT: call void @llvm.assume(i1 [[CMP]]) - // CHECK-NEXT: [[MAT:%.*]] = load <4 x i32>, ptr {{.*}}, align 4{{$}} + // CHECK-NEXT: [[MAT:%.*]] = load <4 x i32>, ptr {{.*}}, align 4, !noundef [[NOUNDEF:![0-9]+]]{{$}} // CHECK-NEXT: [[MATINS:%.*]] = insertelement <4 x i32> [[MAT]], i32 [[E]], i64 [[IDX2]] // CHECK-NEXT: store <4 x i32> [[MATINS]], ptr {{.*}}, align 4 // CHECK-NEXT: ret void @@ -269,7 +269,7 @@ // CHECK-NEXT: [[IDX2:%.*]] = add i64 [[IDX1]], [[I_EXT]] // OPT-NEXT: [[CMP:%.*]] = icmp ult i64 [[IDX2]], 24 // OPT-NEXT: call void @llvm.assume(i1 [[CMP]]) - // CHECK-NEXT: [[MAT:%.*]] = load <24 x float>, ptr {{.*}}, align 4{{$}} + // CHECK-NEXT: [[MAT:%.*]] = load <24 x float>, ptr {{.*}}, align 4, !noundef [[NOUNDEF]]{{$}} // CHECK-NEXT: [[MATINS:%.*]] = insertelement <24 x float> [[MAT]], float [[E]], i64 [[IDX2]] // CHECK-NEXT: store <24 x float> [[MATINS]], ptr {{.*}}, align 4 // CHECK-NEXT: ret void @@ -394,7 +394,7 @@ // CHECK-NEXT: [[IDX2:%.*]] = add i64 [[IDX1]], [[I_EXT]] // OPT-NEXT: [[CMP:%.*]] = icmp ult i64 [[IDX2]], 16 // OPT-NEXT: call void @llvm.assume(i1 [[CMP]]) - // CHECK-NEXT: [[MAT:%.*]] = load <16 x float>, ptr %result, align 4{{$}} + // CHECK-NEXT: [[MAT:%.*]] = load <16 x float>, ptr %result, align 4, !noundef [[NOUNDEF]]{{$}} // CHECK-NEXT: [[MATINS:%.*]] = insertelement <16 x float> [[MAT]], float 1.000000e+00, i64 [[IDX2]] // CHECK-NEXT: store <16 x float> [[MATINS]], ptr %result, align 4 // CHECK-NEXT: br label %for.inc @@ -426,7 +426,7 @@ // CHECK-NEXT: [[IDX2:%.*]] = add i64 [[IDX1]], [[I_EXT]] // OPT-NEXT: [[CMP:%.*]] = icmp ult i64 [[IDX2]], 25 // OPT-NEXT: call void @llvm.assume(i1 [[CMP]]) - // CHECK-NEXT: [[MAT:%.*]] = load <25 x i32>, ptr %result, align 4{{$}} + // CHECK-NEXT: [[MAT:%.*]] = load <25 x i32>, ptr %result, align 4, !noundef [[NOUNDEF]]{{$}} // CHECK-NEXT: [[MATINS:%.*]] = insertelement <25 x i32> [[MAT]], i32 1, i64 [[IDX2]] // CHECK-NEXT: store <25 x i32> [[MATINS]], ptr %result, align 4 // CHECK-NEXT: br label %for.inc diff --git a/clang/test/CodeGenCXX/vector-noundef.cpp b/clang/test/CodeGenCXX/vector-noundef.cpp --- a/clang/test/CodeGenCXX/vector-noundef.cpp +++ b/clang/test/CodeGenCXX/vector-noundef.cpp @@ -115,3 +115,65 @@ void vectorSubsection(VecOfTwoFloats& vec2, VecOfFourFloats& vec4) { vec2 = vec4.xy; } + +// CHECK-LABEL: @_Z18vectorStoreElementRDv2_ff( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VEC2_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[F_ADDR:%.*]] = alloca float, align 4 +// CHECK-NEXT: store ptr [[VEC2:%.*]], ptr [[VEC2_ADDR]], align 8 +// CHECK-NEXT: store float [[F:%.*]], ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[F_ADDR]], align 4, !noundef [[NOUNDEF2]] +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[VEC2_ADDR]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load <2 x float>, ptr [[TMP1]], align 8, !noundef [[NOUNDEF2]] +// CHECK-NEXT: [[TMP3:%.*]] = insertelement <2 x float> [[TMP2]], float [[TMP0]], i64 0 +// CHECK-NEXT: store <2 x float> [[TMP3]], ptr [[TMP1]], align 8 +// CHECK-NEXT: ret void +// +// DISABLE-LABEL: @_Z18vectorStoreElementRDv2_ff( +// DISABLE-NEXT: entry: +// DISABLE-NEXT: [[VEC2_ADDR:%.*]] = alloca ptr, align 8 +// DISABLE-NEXT: [[F_ADDR:%.*]] = alloca float, align 4 +// DISABLE-NEXT: store ptr [[VEC2:%.*]], ptr [[VEC2_ADDR]], align 8 +// DISABLE-NEXT: store float [[F:%.*]], ptr [[F_ADDR]], align 4 +// DISABLE-NEXT: [[TMP0:%.*]] = load float, ptr [[F_ADDR]], align 4 +// DISABLE-NEXT: [[TMP1:%.*]] = load ptr, ptr [[VEC2_ADDR]], align 8 +// DISABLE-NEXT: [[TMP2:%.*]] = load <2 x float>, ptr [[TMP1]], align 8 +// DISABLE-NEXT: [[TMP3:%.*]] = insertelement <2 x float> [[TMP2]], float [[TMP0]], i64 0 +// DISABLE-NEXT: store <2 x float> [[TMP3]], ptr [[TMP1]], align 8 +// DISABLE-NEXT: ret void +// +void vectorStoreElement(VecOfTwoFloats& vec2, float f) { + vec2.x = f; +} + +// CHECK-LABEL: @_Z12vectorRotateRDv4_f( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VEC4_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[VEC4:%.*]], ptr [[VEC4_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VEC4_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load <4 x float>, ptr [[TMP0]], align 16, !noundef [[NOUNDEF2]] +// CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x float> [[TMP1]], <4 x float> poison, <3 x i32> +// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[VEC4_ADDR]], align 8 +// CHECK-NEXT: [[TMP4:%.*]] = load <4 x float>, ptr [[TMP3]], align 16, !noundef [[NOUNDEF2]] +// CHECK-NEXT: [[TMP5:%.*]] = shufflevector <3 x float> [[TMP2]], <3 x float> poison, <4 x i32> +// CHECK-NEXT: [[TMP6:%.*]] = shufflevector <4 x float> [[TMP4]], <4 x float> [[TMP5]], <4 x i32> +// CHECK-NEXT: store <4 x float> [[TMP6]], ptr [[TMP3]], align 16 +// CHECK-NEXT: ret void +// +// DISABLE-LABEL: @_Z12vectorRotateRDv4_f( +// DISABLE-NEXT: entry: +// DISABLE-NEXT: [[VEC4_ADDR:%.*]] = alloca ptr, align 8 +// DISABLE-NEXT: store ptr [[VEC4:%.*]], ptr [[VEC4_ADDR]], align 8 +// DISABLE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VEC4_ADDR]], align 8 +// DISABLE-NEXT: [[TMP1:%.*]] = load <4 x float>, ptr [[TMP0]], align 16 +// DISABLE-NEXT: [[TMP2:%.*]] = shufflevector <4 x float> [[TMP1]], <4 x float> poison, <3 x i32> +// DISABLE-NEXT: [[TMP3:%.*]] = load ptr, ptr [[VEC4_ADDR]], align 8 +// DISABLE-NEXT: [[TMP4:%.*]] = load <4 x float>, ptr [[TMP3]], align 16 +// DISABLE-NEXT: [[TMP5:%.*]] = shufflevector <3 x float> [[TMP2]], <3 x float> poison, <4 x i32> +// DISABLE-NEXT: [[TMP6:%.*]] = shufflevector <4 x float> [[TMP4]], <4 x float> [[TMP5]], <4 x i32> +// DISABLE-NEXT: store <4 x float> [[TMP6]], ptr [[TMP3]], align 16 +// DISABLE-NEXT: ret void +// +void vectorRotate(VecOfFourFloats& vec4) { + vec4.xyz = vec4.zyx; +}