[llvm] r288978 - InstCombine: Fold bitcast of vector to FP scalar

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 7 12:56:11 PST 2016


Author: arsenm
Date: Wed Dec  7 14:56:11 2016
New Revision: 288978

URL: http://llvm.org/viewvc/llvm-project?rev=288978&view=rev
Log:
InstCombine: Fold bitcast of vector to FP scalar

Modified:
    llvm/trunk/lib/Analysis/ConstantFolding.cpp
    llvm/trunk/test/Transforms/InstCombine/bitcast.ll

Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=288978&r1=288977&r2=288978&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original)
+++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Wed Dec  7 14:56:11 2016
@@ -88,7 +88,7 @@ static Constant *foldConstVectorToAPInt(
   return nullptr;
 }
 
-// Constant fold bitcast, symbolically evaluating it with DataLayout.
+/// Constant fold bitcast, symbolically evaluating it with DataLayout.
 /// This always returns a non-null constant, but it may be a
 /// ConstantExpr if unfoldable.
 Constant *FoldBitCast(Constant *C, Type *DestTy, const DataLayout &DL) {
@@ -99,31 +99,33 @@ Constant *FoldBitCast(Constant *C, Type
       !DestTy->isPtrOrPtrVectorTy()) // Don't get ones for ptr types!
     return Constant::getAllOnesValue(DestTy);
 
-  // Handle a vector->integer cast.
-  if (auto *IT = dyn_cast<IntegerType>(DestTy)) {
-    auto *VTy = dyn_cast<VectorType>(C->getType());
-    if (!VTy)
-      return ConstantExpr::getBitCast(C, DestTy);
-
-    unsigned NumSrcElts = VTy->getNumElements();
-    Type *SrcEltTy = VTy->getElementType();
-
-    // If the vector is a vector of floating point, convert it to vector of int
-    // to simplify things.
-    if (SrcEltTy->isFloatingPointTy()) {
-      unsigned FPWidth = SrcEltTy->getPrimitiveSizeInBits();
-      Type *SrcIVTy =
-        VectorType::get(IntegerType::get(C->getContext(), FPWidth), NumSrcElts);
-      // Ask IR to do the conversion now that #elts line up.
-      C = ConstantExpr::getBitCast(C, SrcIVTy);
-    }
+  if (auto *VTy = dyn_cast<VectorType>(C->getType())) {
+    // Handle a vector->scalar integer/fp cast.
+    if (isa<IntegerType>(DestTy) || DestTy->isFloatingPointTy()) {
+      unsigned NumSrcElts = VTy->getNumElements();
+      Type *SrcEltTy = VTy->getElementType();
+
+      // If the vector is a vector of floating point, convert it to vector of int
+      // to simplify things.
+      if (SrcEltTy->isFloatingPointTy()) {
+        unsigned FPWidth = SrcEltTy->getPrimitiveSizeInBits();
+        Type *SrcIVTy =
+          VectorType::get(IntegerType::get(C->getContext(), FPWidth), NumSrcElts);
+        // Ask IR to do the conversion now that #elts line up.
+        C = ConstantExpr::getBitCast(C, SrcIVTy);
+      }
+
+      APInt Result(DL.getTypeSizeInBits(DestTy), 0);
+      if (Constant *CE = foldConstVectorToAPInt(Result, DestTy, C,
+                                                SrcEltTy, NumSrcElts, DL))
+        return CE;
 
-    APInt Result(IT->getBitWidth(), 0);
-    if (Constant *CE = foldConstVectorToAPInt(Result, DestTy, C,
-                                              SrcEltTy, NumSrcElts, DL))
-      return CE;
+      if (isa<IntegerType>(DestTy))
+        return ConstantInt::get(DestTy, Result);
 
-    return ConstantInt::get(IT, Result);
+      APFloat FP(DestTy->getFltSemantics(), Result);
+      return ConstantFP::get(DestTy->getContext(), FP);
+    }
   }
 
   // The code below only handles casts to vectors currently.

Modified: llvm/trunk/test/Transforms/InstCombine/bitcast.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/bitcast.ll?rev=288978&r1=288977&r2=288978&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/bitcast.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/bitcast.ll Wed Dec  7 14:56:11 2016
@@ -449,3 +449,67 @@ define i8 @test8() {
   %res = bitcast <8 x i1> <i1 true, i1 true, i1 false, i1 true, i1 false, i1 true, i1 false, i1 true> to i8
   ret i8 %res
 }
+
+ at g = internal unnamed_addr global i32 undef
+
+; CHECK-LABEL: @constant_fold_vector_to_double(
+; CHECK: store volatile double 1.000000e+00,
+; CHECK: store volatile double 1.000000e+00,
+; CHECK: store volatile double 1.000000e+00,
+; CHECK: store volatile double 1.000000e+00,
+
+; CHECK: store volatile double 0xFFFFFFFFFFFFFFFF,
+; CHECK: store volatile double 0x162E000004D2,
+
+; CHECK: store volatile double bitcast (<2 x i32> <i32 1234, i32 ptrtoint (i32* @g to i32)> to double),
+; CHECK: store volatile double 0x400000003F800000,
+
+; CHECK: store volatile double 0.000000e+00,
+; CHECK: store volatile double 0.000000e+00,
+; CHECK: store volatile double 0.000000e+00,
+; CHECK: store volatile double 0.000000e+00,
+; CHECK: store volatile double 0.000000e+00,
+; CHECK: store volatile double 0.000000e+00,
+define void @constant_fold_vector_to_double() {
+  store volatile double bitcast (<1 x i64> <i64 4607182418800017408> to double), double* undef
+  store volatile double bitcast (<2 x i32> <i32 0, i32 1072693248> to double), double* undef
+  store volatile double bitcast (<4 x i16> <i16 0, i16 0, i16 0, i16 16368> to double), double* undef
+  store volatile double bitcast (<8 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 240, i8 63> to double), double* undef
+
+  store volatile double bitcast (<2 x i32> <i32 -1, i32 -1> to double), double* undef
+  store volatile double bitcast (<2 x i32> <i32 1234, i32 5678> to double), double* undef
+
+  store volatile double bitcast (<2 x i32> <i32 1234, i32 ptrtoint (i32* @g to i32)> to double), double* undef
+  store volatile double bitcast (<2 x float> <float 1.0, float 2.0> to double), double* undef
+
+  store volatile double bitcast (<2 x i32> zeroinitializer to double), double* undef
+  store volatile double bitcast (<4 x i16> zeroinitializer to double), double* undef
+  store volatile double bitcast (<8 x i8> zeroinitializer to double), double* undef
+  store volatile double bitcast (<16 x i4> zeroinitializer to double), double* undef
+  store volatile double bitcast (<32 x i2> zeroinitializer to double), double* undef
+  store volatile double bitcast (<64 x i1> zeroinitializer to double), double* undef
+  ret void
+}
+
+; CHECK-LABEL: @constant_fold_vector_to_float(
+; CHECK: store volatile float 1.000000e+00,
+; CHECK: store volatile float 1.000000e+00,
+; CHECK: store volatile float 1.000000e+00,
+; CHECK: store volatile float 1.000000e+00,
+define void @constant_fold_vector_to_float() {
+  store volatile float bitcast (<1 x i32> <i32 1065353216> to float), float* undef
+  store volatile float bitcast (<2 x i16> <i16 0, i16 16256> to float), float* undef
+  store volatile float bitcast (<4 x i8> <i8 0, i8 0, i8 128, i8 63> to float), float* undef
+  store volatile float bitcast (<32 x i1> <i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 1, i1 1, i1 1, i1 1, i1 1, i1 1, i1 1, i1 0, i1 0> to float), float* undef
+
+  ret void
+}
+
+; CHECK-LABEL: @constant_fold_vector_to_half(
+; CHECK: store volatile half 0xH4000,
+; CHECK: store volatile half 0xH4000,
+define void @constant_fold_vector_to_half() {
+  store volatile half bitcast (<2 x i8> <i8 0, i8 64> to half), half* undef
+  store volatile half bitcast (<4 x i4> <i4 0, i4 0, i4 0, i4 4> to half), half* undef
+  ret void
+}




More information about the llvm-commits mailing list