diff options
author | Sanjay Patel <spatel@rotateright.com> | 2018-06-21 23:56:59 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2018-06-21 23:56:59 +0000 |
commit | 4784e1506e37f80efcfed000ee2879260a1cd576 (patch) | |
tree | 46e77da1686b2c53ba9519aa3e4258bf79016c70 | |
parent | 23408c25f3c3bc5e80effe3d4750392f96d397ad (diff) | |
download | bcm5719-llvm-4784e1506e37f80efcfed000ee2879260a1cd576.tar.gz bcm5719-llvm-4784e1506e37f80efcfed000ee2879260a1cd576.zip |
[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.
llvm-svn: 335312
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp | 10 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/shuffle_select.ll | 5 |
2 files changed, 11 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp index d8546c7b89a..01b1f4cdf3c 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp @@ -1166,6 +1166,13 @@ static Instruction *foldSelectShuffles(ShuffleVectorInst &Shuf) { 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(ShuffleVectorInst &Shuf) { 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. diff --git a/llvm/test/Transforms/InstCombine/shuffle_select.ll b/llvm/test/Transforms/InstCombine/shuffle_select.ll index e3e2dde0915..ed9266a8459 100644 --- a/llvm/test/Transforms/InstCombine/shuffle_select.ll +++ b/llvm/test/Transforms/InstCombine/shuffle_select.ll @@ -224,12 +224,13 @@ define <4 x double> @fdiv(<4 x double> %v0) { 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 |