Implement support for simplifying vector comparisons by 0.0 and 1.0 like we
authorChris Lattner <sabre@nondot.org>
Mon, 11 Aug 2008 22:06:05 +0000 (22:06 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 11 Aug 2008 22:06:05 +0000 (22:06 +0000)
do for scalars.  Patch contributed by Nicolas Capens

This also generalizes the previous xforms to work on long double, now that
isExactlyValue works for long double.

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

lib/Transforms/Scalar/InstructionCombining.cpp
test/Transforms/InstCombine/mul.ll

index eebb7cf82f53b4b0642c3b70e9f5e213cd380b9b..bdea6e40d21e2fd527d6334b8505cc129a1f3f59 100644 (file)
@@ -2480,10 +2480,17 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
 
       // "In IEEE floating point, x*1 is not equivalent to x for nans.  However,
       // ANSI says we can drop signals, so we can do this anyway." (from GCC)
-      // We need a better interface for long double here.
-      if (Op1->getType() == Type::FloatTy || Op1->getType() == Type::DoubleTy)
-        if (Op1F->isExactlyValue(1.0))
-          return ReplaceInstUsesWith(I, Op0);  // Eliminate 'mul double %X, 1.0'
+      if (Op1F->isExactlyValue(1.0))
+        return ReplaceInstUsesWith(I, Op0);  // Eliminate 'mul double %X, 1.0'
+    } else if (isa<VectorType>(Op1->getType())) {
+      if (isa<ConstantAggregateZero>(Op1))
+        return ReplaceInstUsesWith(I, Op1);
+      
+      // As above, vector X*splat(1.0) -> X in all defined cases.
+      if (ConstantVector *Op1V = dyn_cast<ConstantVector>(Op1))
+        if (ConstantFP *F = dyn_cast_or_null<ConstantFP>(Op1V->getSplatValue()))
+          if (F->isExactlyValue(1.0))
+            return ReplaceInstUsesWith(I, Op0);
     }
     
     if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0))
@@ -11636,3 +11643,4 @@ FunctionPass *llvm::createInstructionCombiningPass() {
   return new InstCombiner();
 }
 
+
index 8e9ab8d4213ec1de11575c099e21d444cbf93944..1a7402543418b69f00204ac66ff128fb4b707716 100644 (file)
@@ -1,7 +1,5 @@
 ; This test makes sure that mul instructions are properly eliminated.
-;
 ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep mul
-; END.
 
 define i32 @test1(i32 %A) {
         %B = mul i32 %A, 1              ; <i32> [#uses=1]
@@ -78,3 +76,18 @@ define i32 @test12(i8 %a, i32 %b) {
         ret i32 %e
 }
 
+; PR2642
+define internal void @test13(<4 x float>*) {
+       load <4 x float>* %0, align 1
+       mul <4 x float> %2, < float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00 >
+       store <4 x float> %3, <4 x float>* %0, align 1
+       ret void
+}
+
+define internal void @test14(<4 x float>*) {
+       load <4 x float>* %0, align 1
+       mul <4 x float> %2, zeroinitializer
+       store <4 x float> %3, <4 x float>* %0, align 1
+       ret void
+}
+