[llvm] r335312 - [InstCombine] fix shuffle-of-binops bug

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 21 16:57:00 PDT 2018


Author: spatel
Date: Thu Jun 21 16:56:59 2018
New Revision: 335312

URL: http://llvm.org/viewvc/llvm-project?rev=335312&view=rev
Log:
[InstCombine] fix shuffle-of-binops bug

With non-commutative binops, we could be using the same
variable value as operand 0 in 1 binop and operand 1 in 
the other, so we have to check for that possibility and
bail out.

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
    llvm/trunk/test/Transforms/InstCombine/shuffle_select.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineVectorOps.cpp?rev=335312&r1=335311&r2=335312&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineVectorOps.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineVectorOps.cpp Thu Jun 21 16:56:59 2018
@@ -1166,6 +1166,13 @@ static Instruction *foldSelectShuffles(S
   if (isa<Constant>(X))
     return nullptr;
 
+  // Constant operands must be on the same side of each binop. We can't fold:
+  // shuffle (sdiv X, C0), (sdiv C1, X).
+  bool B00IsConst = isa<Constant>(B0->getOperand(0));
+  bool B10IsConst = isa<Constant>(B1->getOperand(0));
+  if (B00IsConst != B10IsConst)
+    return nullptr;
+
   // Remove a binop and the shuffle by rearranging the constant:
   // shuffle (op X, C0), (op X, C1), M --> op X, C'
   // shuffle (op C0, X), (op C1, X), M --> op C', X
@@ -1178,8 +1185,7 @@ static Instruction *foldSelectShuffles(S
     NewC = getSafeVectorConstantForIntDivRem(NewC);
 
   BinaryOperator::BinaryOps Opc = B0->getOpcode();
-  bool Op0IsConst = isa<Constant>(B0->getOperand(0));
-  Instruction *NewBO = Op0IsConst ? BinaryOperator::Create(Opc, NewC, X) :
+  Instruction *NewBO = B00IsConst ? BinaryOperator::Create(Opc, NewC, X) :
                                     BinaryOperator::Create(Opc, X, NewC);
 
   // Flags are intersected from the 2 source binops.

Modified: llvm/trunk/test/Transforms/InstCombine/shuffle_select.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/shuffle_select.ll?rev=335312&r1=335311&r2=335312&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/shuffle_select.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/shuffle_select.ll Thu Jun 21 16:56:59 2018
@@ -224,12 +224,13 @@ define <4 x double> @fdiv(<4 x double> %
   ret <4 x double> %t3
 }
 
-; FIXME:
 ; The variable operand must be either the first operand or second operand in both binops.
 
 define <4 x double> @frem(<4 x double> %v0) {
 ; CHECK-LABEL: @frem(
-; CHECK-NEXT:    [[T3:%.*]] = frem <4 x double> <double 1.000000e+00, double 2.000000e+00, double 7.000000e+00, double 8.000000e+00>, [[V0:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = frem <4 x double> <double 1.000000e+00, double 2.000000e+00, double 3.000000e+00, double 4.000000e+00>, [[V0:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = frem <4 x double> [[V0]], <double 5.000000e+00, double 6.000000e+00, double 7.000000e+00, double 8.000000e+00>
+; CHECK-NEXT:    [[T3:%.*]] = shufflevector <4 x double> [[T1]], <4 x double> [[T2]], <4 x i32> <i32 0, i32 1, i32 6, i32 7>
 ; CHECK-NEXT:    ret <4 x double> [[T3]]
 ;
   %t1 = frem <4 x double> <double 1.0, double 2.0, double 3.0, double 4.0>, %v0




More information about the llvm-commits mailing list