[clang] 348f22e - Correct gcc vector splat conversion from float to int-vector

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Fri Dec 13 12:27:48 PST 2019


Author: Erich Keane
Date: 2019-12-13T12:27:31-08:00
New Revision: 348f22eac83d9a3ee946e41be43fe507f04a89b6

URL: https://github.com/llvm/llvm-project/commit/348f22eac83d9a3ee946e41be43fe507f04a89b6
DIFF: https://github.com/llvm/llvm-project/commit/348f22eac83d9a3ee946e41be43fe507f04a89b6.diff

LOG: 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.

Added: 
    

Modified: 
    clang/lib/Sema/SemaExpr.cpp
    clang/test/CodeGenCXX/vector-splat-conversion.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index a941d524b7f2..620ec30b1285 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -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()) {
 

diff  --git a/clang/test/CodeGenCXX/vector-splat-conversion.cpp b/clang/test/CodeGenCXX/vector-splat-conversion.cpp
index 805f9f5bab15..618ad76ce691 100644
--- a/clang/test/CodeGenCXX/vector-splat-conversion.cpp
+++ b/clang/test/CodeGenCXX/vector-splat-conversion.cpp
@@ -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]]
+}


        


More information about the cfe-commits mailing list