forked from OSchip/llvm-project
Correct gcc vector splat conversion from float to int-vector
In looking into some other code, I came across this issue where a float converted to a gcc integer vector via a splat causes it to miss the float-to-integral cast, which causes some REALLY strange codegen bugs. The AST looked like: `-ImplicitCastExpr <col:13> 'gcc_int_2':'__attribute__((__vector_size__(2 * sizeof(int)))) int' <VectorSplat> `-ImplicitCastExpr <col:13> 'float' <LValueToRValue> `-DeclRefExpr <col:13> 'float' lvalue ParmVar 0x556f16a5dc90 'f' 'float' Despite the type of the VectorSplat cast as printed, it ended up becoming a vector of float, which caused non-matching instructions. For example, IntVector + a float constant resulted in: add <2 x i32> %8, <2 x float> <float 3.000000e+00, float 3.000000e+00> This patch corrects the conversion so that the float is first converted to an integral, THEN splatted.
This commit is contained in:
parent
a0f43b0043
commit
348f22eac8
|
@ -8973,6 +8973,12 @@ static bool tryGCCVectorConvertAndSplat(Sema &S, ExprResult *Scalar,
|
|||
return true;
|
||||
|
||||
ScalarCast = CK_IntegralCast;
|
||||
} else if (VectorEltTy->isIntegralType(S.Context) &&
|
||||
ScalarTy->isRealFloatingType()) {
|
||||
if (S.Context.getTypeSize(VectorEltTy) == S.Context.getTypeSize(ScalarTy))
|
||||
ScalarCast = CK_FloatingToIntegral;
|
||||
else
|
||||
return true;
|
||||
} else if (VectorEltTy->isRealFloatingType()) {
|
||||
if (ScalarTy->isRealFloatingType()) {
|
||||
|
||||
|
|
|
@ -49,3 +49,14 @@ void BoolConversion() {
|
|||
// CHECK: store <4 x i128> zeroinitializer
|
||||
constexpr bigint4 cBigintsF = (bigint4)false;
|
||||
}
|
||||
|
||||
typedef __attribute__((vector_size(8))) int gcc_int_2;
|
||||
gcc_int_2 FloatToIntConversion(gcc_int_2 Int2, float f) {
|
||||
return Int2 + f;
|
||||
// CHECK: %[[LOAD_INT:.+]] = load <2 x i32>
|
||||
// CHECK: %[[LOAD:.+]] = load float, float*
|
||||
// CHECK: %[[CONV:.+]] = fptosi float %[[LOAD]] to i32
|
||||
// CHECK: %[[INSERT:.+]] = insertelement <2 x i32> undef, i32 %[[CONV]], i32 0
|
||||
// CHECK: %[[SPLAT:.+]] = shufflevector <2 x i32> %[[INSERT]], <2 x i32> undef, <2 x i32> zeroinitializer
|
||||
// CHECK: add <2 x i32> %[[LOAD_INT]], %[[SPLAT]]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue