[llvm] r358805 - [X86] Don't turn (and (shl X, C1), C2) into (shl (and X, (C1 >> C2), C2) if the original AND can represented by MOVZX.
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 19 21:38:53 PDT 2019
Author: ctopper
Date: Fri Apr 19 21:38:53 2019
New Revision: 358805
URL: http://llvm.org/viewvc/llvm-project?rev=358805&view=rev
Log:
[X86] Don't turn (and (shl X, C1), C2) into (shl (and X, (C1 >> C2), C2) if the original AND can represented by MOVZX.
The MOVZX doesn't require an immediate to be encoded at all. Though it does use
a 2 byte opcode so its the same size as a 1 byte immediate. But it has a
separate source and dest register so can help avoid copies.
Modified:
llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
llvm/trunk/test/CodeGen/X86/narrow-shl-cst.ll
Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=358805&r1=358804&r2=358805&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Fri Apr 19 21:38:53 2019
@@ -3983,10 +3983,11 @@ void X86DAGToDAGISel::Select(SDNode *Nod
if (!Cst)
break;
+ int64_t Val = Cst->getSExtValue();
+
// If we have an any_extend feeding the AND, look through it to see if there
// is a shift behind it. But only if the AND doesn't use the extended bits.
// FIXME: Generalize this to other ANY_EXTEND than i32 to i64?
- int64_t Val = Cst->getSExtValue();
bool FoundAnyExtend = false;
if (Shift.getOpcode() == ISD::ANY_EXTEND && Shift.hasOneUse() &&
Shift.getOperand(0).getSimpleValueType() == MVT::i32 &&
@@ -4041,26 +4042,44 @@ void X86DAGToDAGISel::Select(SDNode *Nod
};
int64_t ShiftedVal;
- if (CanShrinkImmediate(ShiftedVal)) {
- SDValue X = Shift.getOperand(0);
- if (FoundAnyExtend) {
- SDValue NewX = CurDAG->getNode(ISD::ANY_EXTEND, dl, NVT, X);
- insertDAGNode(*CurDAG, SDValue(Node, 0), NewX);
- X = NewX;
- }
+ if (!CanShrinkImmediate(ShiftedVal))
+ break;
+
+ // Ok, we can reorder to get a smaller immediate.
+
+ // But, its possible the original immediate allowed an AND to become MOVZX.
+ // Doing this late due to avoid the MakedValueIsZero call as late as
+ // possible.
+ if (Opcode == ISD::AND) {
+ // Find the smallest zext this could possibly be.
+ unsigned ZExtWidth = Cst->getAPIntValue().getActiveBits();
+ ZExtWidth = PowerOf2Ceil(std::max(ZExtWidth, 8U));
+
+ // Figure out which bits need to be zero to achieve that mask.
+ APInt NeededMask = APInt::getLowBitsSet(NVT.getSizeInBits(),
+ ZExtWidth);
+ NeededMask &= ~Cst->getAPIntValue();
+
+ if (CurDAG->MaskedValueIsZero(Node->getOperand(0), NeededMask))
+ break;
+ }
- SDValue NewCst = CurDAG->getConstant(ShiftedVal, dl, NVT);
- insertDAGNode(*CurDAG, SDValue(Node, 0), NewCst);
- SDValue NewBinOp = CurDAG->getNode(Opcode, dl, NVT, X, NewCst);
- insertDAGNode(*CurDAG, SDValue(Node, 0), NewBinOp);
- SDValue NewSHL = CurDAG->getNode(ISD::SHL, dl, NVT, NewBinOp,
- Shift.getOperand(1));
- ReplaceNode(Node, NewSHL.getNode());
- SelectCode(NewSHL.getNode());
- return;
+ SDValue X = Shift.getOperand(0);
+ if (FoundAnyExtend) {
+ SDValue NewX = CurDAG->getNode(ISD::ANY_EXTEND, dl, NVT, X);
+ insertDAGNode(*CurDAG, SDValue(Node, 0), NewX);
+ X = NewX;
}
- break;
+ SDValue NewCst = CurDAG->getConstant(ShiftedVal, dl, NVT);
+ insertDAGNode(*CurDAG, SDValue(Node, 0), NewCst);
+ SDValue NewBinOp = CurDAG->getNode(Opcode, dl, NVT, X, NewCst);
+ insertDAGNode(*CurDAG, SDValue(Node, 0), NewBinOp);
+ SDValue NewSHL = CurDAG->getNode(ISD::SHL, dl, NVT, NewBinOp,
+ Shift.getOperand(1));
+ ReplaceNode(Node, NewSHL.getNode());
+ SelectCode(NewSHL.getNode());
+ return;
}
case X86ISD::SMUL:
// i16/i32/i64 are handled with isel patterns.
Modified: llvm/trunk/test/CodeGen/X86/narrow-shl-cst.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/narrow-shl-cst.ll?rev=358805&r1=358804&r2=358805&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/narrow-shl-cst.ll (original)
+++ llvm/trunk/test/CodeGen/X86/narrow-shl-cst.ll Fri Apr 19 21:38:53 2019
@@ -138,9 +138,8 @@ define i64 @test11(i64 %x) nounwind {
define i32 @test12(i32 %x, i32* %y) nounwind {
; CHECK-LABEL: test12:
; CHECK: # %bb.0:
-; CHECK-NEXT: movl %edi, %eax
-; CHECK-NEXT: andl $127, %eax
-; CHECK-NEXT: addl %eax, %eax
+; CHECK-NEXT: addl %edi, %edi
+; CHECK-NEXT: movzbl %dil, %eax
; CHECK-NEXT: movl %eax, (%rsi)
; CHECK-NEXT: retq
%and = shl i32 %x, 1
@@ -152,9 +151,8 @@ define i32 @test12(i32 %x, i32* %y) noun
define i64 @test13(i64 %x, i64* %y) nounwind {
; CHECK-LABEL: test13:
; CHECK: # %bb.0:
-; CHECK-NEXT: movq %rdi, %rax
-; CHECK-NEXT: andl $127, %eax
-; CHECK-NEXT: addq %rax, %rax
+; CHECK-NEXT: addl %edi, %edi
+; CHECK-NEXT: movzbl %dil, %eax
; CHECK-NEXT: movq %rax, (%rsi)
; CHECK-NEXT: retq
%and = shl i64 %x, 1
More information about the llvm-commits
mailing list