[llvm] r358804 - [X86] Turn (and (anyextend (shl X, C1), C2)) into (shl (and (anyextend X), (C1 >> C2), C2) if the AND could match a movzx.
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 19 21:38:49 PDT 2019
Author: ctopper
Date: Fri Apr 19 21:38:49 2019
New Revision: 358804
URL: http://llvm.org/viewvc/llvm-project?rev=358804&view=rev
Log:
[X86] Turn (and (anyextend (shl X, C1), C2)) into (shl (and (anyextend X), (C1 >> C2), C2) if the AND could match a movzx.
There's one slight regression in here because we don't check that the immediate
already allowed movzx before the shift. I'll fix that next.
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=358804&r1=358803&r2=358804&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Fri Apr 19 21:38:49 2019
@@ -3976,22 +3976,36 @@ void X86DAGToDAGISel::Select(SDNode *Nod
// For operations of the form (x << C1) op C2, check if we can use a smaller
// encoding for C2 by transforming it into (x op (C2>>C1)) << C1.
- SDValue N0 = Node->getOperand(0);
+ SDValue Shift = Node->getOperand(0);
SDValue N1 = Node->getOperand(1);
- if (N0->getOpcode() != ISD::SHL || !N0->hasOneUse())
+ ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(N1);
+ if (!Cst)
+ break;
+
+ // 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 &&
+ isUInt<32>(Val)) {
+ FoundAnyExtend = true;
+ Shift = Shift.getOperand(0);
+ }
+
+ if (Shift.getOpcode() != ISD::SHL || !Shift.hasOneUse())
break;
// i8 is unshrinkable, i16 should be promoted to i32.
if (NVT != MVT::i32 && NVT != MVT::i64)
break;
- ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(N1);
- ConstantSDNode *ShlCst = dyn_cast<ConstantSDNode>(N0->getOperand(1));
- if (!Cst || !ShlCst)
+ ConstantSDNode *ShlCst = dyn_cast<ConstantSDNode>(Shift.getOperand(1));
+ if (!ShlCst)
break;
- int64_t Val = Cst->getSExtValue();
uint64_t ShAmt = ShlCst->getZExtValue();
// Make sure that we don't change the operation by removing bits.
@@ -4028,13 +4042,19 @@ 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;
+ }
+
SDValue NewCst = CurDAG->getConstant(ShiftedVal, dl, NVT);
insertDAGNode(*CurDAG, SDValue(Node, 0), NewCst);
- SDValue NewBinOp = CurDAG->getNode(Opcode, dl, NVT, N0->getOperand(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,
- N0->getOperand(1));
+ Shift.getOperand(1));
ReplaceNode(Node, NewSHL.getNode());
SelectCode(NewSHL.getNode());
return;
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=358804&r1=358803&r2=358804&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:49 2019
@@ -152,8 +152,9 @@ define i32 @test12(i32 %x, i32* %y) noun
define i64 @test13(i64 %x, i64* %y) nounwind {
; CHECK-LABEL: test13:
; CHECK: # %bb.0:
-; CHECK-NEXT: addl %edi, %edi
-; CHECK-NEXT: movzbl %dil, %eax
+; CHECK-NEXT: movq %rdi, %rax
+; CHECK-NEXT: andl $127, %eax
+; CHECK-NEXT: addq %rax, %rax
; CHECK-NEXT: movq %rax, (%rsi)
; CHECK-NEXT: retq
%and = shl i64 %x, 1
@@ -212,9 +213,8 @@ define i32 @test17(i32 %x) nounwind {
define i64 @test18(i64 %x) nounwind {
; CHECK-LABEL: test18:
; CHECK: # %bb.0:
-; CHECK-NEXT: movq %rdi, %rax
-; CHECK-NEXT: shll $10, %eax
-; CHECK-NEXT: andl $261120, %eax # imm = 0x3FC00
+; CHECK-NEXT: movzbl %dil, %eax
+; CHECK-NEXT: shlq $10, %rax
; CHECK-NEXT: retq
%and = shl i64 %x, 10
%shl = and i64 %and, 261120
@@ -235,9 +235,8 @@ define i32 @test19(i32 %x) nounwind {
define i64 @test20(i64 %x) nounwind {
; CHECK-LABEL: test20:
; CHECK: # %bb.0:
-; CHECK-NEXT: movq %rdi, %rax
-; CHECK-NEXT: shll $10, %eax
-; CHECK-NEXT: andl $67107840, %eax # imm = 0x3FFFC00
+; CHECK-NEXT: movzwl %di, %eax
+; CHECK-NEXT: shlq $10, %rax
; CHECK-NEXT: retq
%and = shl i64 %x, 10
%shl = and i64 %and, 67107840
More information about the llvm-commits
mailing list