diff options
| author | Craig Topper <craig.topper@intel.com> | 2018-02-05 16:54:07 +0000 |
|---|---|---|
| committer | Craig Topper <craig.topper@intel.com> | 2018-02-05 16:54:07 +0000 |
| commit | 57e06431600f60df5831bf3d8315fedac360ca22 (patch) | |
| tree | 2d190b4f1d3767104d4ee5258dff7e960267f297 /llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | |
| parent | 22db17cf4334b028fe13e37ed7957eff2ae01ea9 (diff) | |
| download | bcm5719-llvm-57e06431600f60df5831bf3d8315fedac360ca22.tar.gz bcm5719-llvm-57e06431600f60df5831bf3d8315fedac360ca22.zip | |
[X86] Teach X86DAGToDAGISel::shrinkAndImmediate to preserve upper 32 zeroes of a 64 bit mask.
If the upper 32 bits of a 64 bit mask are all zeros, we have special isel patterns to use a 32-bit and instead of a 64-bit and by relying on the impliciting zeroing of 32 bit ops.
This patch teachs shrinkAndImmediate not to break that optimization.
Differential Revision: https://reviews.llvm.org/D42899
llvm-svn: 324249
Diffstat (limited to 'llvm/lib/Target/X86/X86ISelDAGToDAG.cpp')
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index fb48c6466a4..d932b57f244 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -2486,14 +2486,24 @@ bool X86DAGToDAGISel::shrinkAndImmediate(SDNode *And) { if (!And1C) return false; - // Bail out if the mask constant is already negative. It can't shrink more. + // Bail out if the mask constant is already negative. It's can't shrink more. + // If the upper 32 bits of a 64 bit mask are all zeros, we have special isel + // patterns to use a 32-bit and instead of a 64-bit and by relying on the + // implicit zeroing of 32 bit ops. So we should check if the lower 32 bits + // are negative too. APInt MaskVal = And1C->getAPIntValue(); unsigned MaskLZ = MaskVal.countLeadingZeros(); - if (!MaskLZ) + if (!MaskLZ || (VT == MVT::i64 && MaskLZ == 32)) return false; + // Don't extend into the upper 32 bits of a 64 bit mask. + if (VT == MVT::i64 && MaskLZ >= 32) { + MaskLZ -= 32; + MaskVal = MaskVal.trunc(32); + } + SDValue And0 = And->getOperand(0); - APInt HighZeros = APInt::getHighBitsSet(VT.getSizeInBits(), MaskLZ); + APInt HighZeros = APInt::getHighBitsSet(MaskVal.getBitWidth(), MaskLZ); APInt NegMaskVal = MaskVal | HighZeros; // If a negative constant would not allow a smaller encoding, there's no need @@ -2502,6 +2512,12 @@ bool X86DAGToDAGISel::shrinkAndImmediate(SDNode *And) { if (MinWidth > 32 || (MinWidth > 8 && MaskVal.getMinSignedBits() <= 32)) return false; + // Extend masks if we truncated above. + if (VT == MVT::i64 && MaskVal.getBitWidth() < 64) { + NegMaskVal = NegMaskVal.zext(64); + HighZeros = HighZeros.zext(64); + } + // The variable operand must be all zeros in the top bits to allow using the // new, negative constant as the mask. if (!CurDAG->MaskedValueIsZero(And0, HighZeros)) |

