elementwise comparison of vector constants was completely wrong. Fix
authorChris Lattner <sabre@nondot.org>
Thu, 10 Jul 2008 00:08:17 +0000 (00:08 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 10 Jul 2008 00:08:17 +0000 (00:08 +0000)
it for PR2529

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53380 91177308-0d34-0410-b5e6-96231b3b80d8

lib/VMCore/ConstantFold.cpp
test/Transforms/ConstProp/2008-07-07-VectorCompare.ll

index c7accb36862a8c7a04d94a234db299e1bf9f685d..57b6a4e05d17f96b06b2b9dfb6e9259541b1ad3a 100644 (file)
@@ -1350,27 +1350,40 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
     }
   } else if (const ConstantVector *CP1 = dyn_cast<ConstantVector>(C1)) {
     if (const ConstantVector *CP2 = dyn_cast<ConstantVector>(C2)) {
-      if (pred == FCmpInst::FCMP_OEQ || pred == FCmpInst::FCMP_UEQ) {
-        for (unsigned i = 0, e = CP1->getNumOperands(); i != e; ++i) {
-          Constant *C = ConstantExpr::getFCmp(FCmpInst::FCMP_OEQ,
-                                              CP1->getOperand(i),
-                                              CP2->getOperand(i));
-          if (ConstantInt *CB = dyn_cast<ConstantInt>(C))
-            return CB;
-        }
-        // Otherwise, could not decide from any element pairs.
-        return 0;
-      } else if (pred == ICmpInst::ICMP_EQ) {
-        for (unsigned i = 0, e = CP1->getNumOperands(); i != e; ++i) {
-          Constant *C = ConstantExpr::getICmp(ICmpInst::ICMP_EQ,
-                                              CP1->getOperand(i),
-                                              CP2->getOperand(i));
-          if (ConstantInt *CB = dyn_cast<ConstantInt>(C))
-            return CB;
+      // If we can constant fold the comparison of each element, constant fold
+      // the whole vector comparison.
+      SmallVector<Constant*, 4> Elts;
+      const Type *InEltTy = CP1->getOperand(0)->getType();
+      bool isFP = InEltTy->isFloatingPoint();
+      const Type *ResEltTy = InEltTy;
+      if (isFP)
+        ResEltTy = IntegerType::get(InEltTy->getPrimitiveSizeInBits());
+      
+      for (unsigned i = 0, e = CP1->getNumOperands(); i != e; ++i) {
+        // Compare the elements, producing an i1 result or constant expr.
+        Constant *C;
+        if (isFP)
+          C = ConstantExpr::getFCmp(pred, CP1->getOperand(i),
+                                    CP2->getOperand(i));
+        else
+          C = ConstantExpr::getICmp(pred, CP1->getOperand(i),
+                                    CP2->getOperand(i));
+
+        // If it is a bool or undef result, convert to the dest type.
+        if (ConstantInt *CI = dyn_cast<ConstantInt>(C)) {
+          if (CI->isZero())
+            Elts.push_back(Constant::getNullValue(ResEltTy));
+          else
+            Elts.push_back(Constant::getAllOnesValue(ResEltTy));
+        } else if (isa<UndefValue>(C)) {
+          Elts.push_back(UndefValue::get(ResEltTy));
+        } else {
+          break;
         }
-        // Otherwise, could not decide from any element pairs.
-        return 0;
       }
+      
+      if (Elts.size() == CP1->getNumOperands())
+        return ConstantVector::get(&Elts[0], Elts.size());
     }
   }
 
index 35f034a90953b8bf56f300c8b4397e952bc63474..b42b0248496172ce8b360b506ea2c74ab86f1054 100644 (file)
@@ -6,9 +6,17 @@ entry:
         ret <4 x i32> %foo
 }
 
-define <4 x i32> @main(i32 %argc, i8** %argv) {
+define <4 x i32> @test2(i32 %argc, i8** %argv) {
 entry:  
         %foo = vicmp slt <4 x i32> <i32 undef, i32 undef, i32 undef, i32
 undef>, <i32 undef, i32 undef, i32 undef, i32 undef>
         ret <4 x i32> %foo
 }
+
+
+define <4 x i32> @test3() {
+       %foo = vfcmp ueq <4 x float> <float 0.0, float 0.0, float 0.0, float
+undef>, <float 1.0, float 1.0, float 1.0, float undef>
+       ret <4 x i32> %foo
+}
+