diff options
author | Sanjay Patel <spatel@rotateright.com> | 2018-12-03 21:15:17 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2018-12-03 21:15:17 +0000 |
commit | 8c655150827b5d56772e628994db08441c554097 (patch) | |
tree | a3ba34b619e2947c3ca60da932191d5f064b4e84 /llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | |
parent | 660f9c943ff34c3e30708e848407961b462c070d (diff) | |
download | bcm5719-llvm-8c655150827b5d56772e628994db08441c554097.tar.gz bcm5719-llvm-8c655150827b5d56772e628994db08441c554097.zip |
[InstCombine] fix undef propagation bug with shuffle+binop
When we have a shuffle that extends a source vector with undefs
and then do some binop on that, we must make sure that the extra
elements remain undef with that binop if we reverse the order of
the binop and shuffle.
'or' is probably the easiest example to show the bug because
'or C, undef --> -1' (not undef). But there are other
opcode/constant combinations where this is true as shown by
the 'shl' test.
llvm-svn: 348191
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstructionCombining.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 13903d16529..7c9dbcb66cc 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1455,6 +1455,22 @@ Instruction *InstCombiner::foldVectorBinop(BinaryOperator &Inst) { } NewVecC[ShMask[I]] = CElt; } + // If this is a widening shuffle, we must be able to extend with undef + // elements. If the original binop does not produce an undef in the high + // lanes, then this transform is not safe. + // TODO: We could shuffle those non-undef constant values into the + // result by using a constant vector (rather than an undef vector) + // as operand 1 of the new binop, but that might be too aggressive + // for target-independent shuffle creation. + if (I >= SrcVecNumElts) { + Constant *MaybeUndef = + ConstOp1 ? ConstantExpr::get(Opcode, UndefScalar, CElt) + : ConstantExpr::get(Opcode, CElt, UndefScalar); + if (!isa<UndefValue>(MaybeUndef)) { + MayChange = false; + break; + } + } } if (MayChange) { Constant *NewC = ConstantVector::get(NewVecC); |