diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2018-05-31 00:16:58 +0000 |
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2018-05-31 00:16:58 +0000 |
| commit | e5bc4417913a3e606d572a5d661106612d3a99a7 (patch) | |
| tree | ccc5a2460f85e5f3868cbaa0858807f75ee27d38 /llvm/lib/Transforms/InstCombine | |
| parent | ceb595b04e88f6d0da922a9631bb3edf715480fc (diff) | |
| download | bcm5719-llvm-e5bc4417913a3e606d572a5d661106612d3a99a7.tar.gz bcm5719-llvm-e5bc4417913a3e606d572a5d661106612d3a99a7.zip | |
[InstCombine] don't change the size of a select if it would mismatch its condition operands' sizes
Don't always:
cast (select (cmp x, y), z, C) --> select (cmp x, y), (cast z), C'
This is something that came up as far back as D26556, and I lost track of it.
I suspect that this transform is part of the underlying problem that is
inspiring some of the recent proposals that seek to match larger patterns
that include a cast op. Even if that's not true, this transform causes
problems for codegen (particularly with vector types).
A transform to actively match the size of cmp and select operand sizes should
follow. This patch just removes the harmful canonicalization in the other
direction.
Differential Revision: https://reviews.llvm.org/D47163
llvm-svn: 333611
Diffstat (limited to 'llvm/lib/Transforms/InstCombine')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index 522ee968a77..9f297b0aab0 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -283,10 +283,16 @@ Instruction *InstCombiner::commonCastTransforms(CastInst &CI) { } } - // If we are casting a select, then fold the cast into the select. - if (auto *SI = dyn_cast<SelectInst>(Src)) - if (Instruction *NV = FoldOpIntoSelect(CI, SI)) - return NV; + if (auto *Sel = dyn_cast<SelectInst>(Src)) { + // We are casting a select. Try to fold the cast into the select, but only + // if the select does not have a compare instruction with matching operand + // types. Creating a select with operands that are different sizes than its + // condition may inhibit other folds and lead to worse codegen. + auto *Cmp = dyn_cast<CmpInst>(Sel->getCondition()); + if (!Cmp || Cmp->getOperand(0)->getType() != Sel->getType()) + if (Instruction *NV = FoldOpIntoSelect(CI, Sel)) + return NV; + } // If we are casting a PHI, then fold the cast into the PHI. if (auto *PN = dyn_cast<PHINode>(Src)) { |

