diff options
author | Sanjay Patel <spatel@rotateright.com> | 2018-06-01 19:23:18 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2018-06-01 19:23:18 +0000 |
commit | 66f7e19f6a05ca11f62c9e48f8d6ed0c011a47cf (patch) | |
tree | 772820a4df6d329d4fd051f98c7d1ba5f9f9fa39 /llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | |
parent | 36d457c20d86a749e08ecee23eeb2bade5f2ab56 (diff) | |
download | bcm5719-llvm-66f7e19f6a05ca11f62c9e48f8d6ed0c011a47cf.tar.gz bcm5719-llvm-66f7e19f6a05ca11f62c9e48f8d6ed0c011a47cf.zip |
[InstCombine] fix vector shuffle transform to replace undef elements (PR37648)
This bug:
https://bugs.llvm.org/show_bug.cgi?id=37648
...was created with the enhancement to this transform with rL332479.
The urem test shows the disaster potential: any undef divisor lane makes
the whole op undef.
The test diffs show that vector demanded elements turns some of the potential,
but not all, unused binop operands back into undef already.
llvm-svn: 333782
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 7ccb65d6531..7a34419bfe9 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1421,6 +1421,22 @@ Value *InstCombiner::SimplifyVectorOp(BinaryOperator &Inst) { } } if (MayChange) { + // It's not safe to use a vector with undef elements because the entire + // instruction can be folded to undef (for example, div/rem divisors). + // Replace undef lanes with the first non-undef element. Vector demanded + // elements can change those back to undef values if that is safe. + Constant *SafeDummyConstant = nullptr; + for (unsigned i = 0; i < VWidth; ++i) { + if (!isa<UndefValue>(NewVecC[i])) { + SafeDummyConstant = NewVecC[i]; + break; + } + } + assert(SafeDummyConstant && "Undef constant vector was not simplified?"); + for (unsigned i = 0; i < VWidth; ++i) + if (isa<UndefValue>(NewVecC[i])) + NewVecC[i] = SafeDummyConstant; + // Op(shuffle(V1, Mask), C) -> shuffle(Op(V1, NewC), Mask) // Op(C, shuffle(V1, Mask)) -> shuffle(Op(NewC, V1), Mask) Constant *NewC = ConstantVector::get(NewVecC); |