[llvm] r357049 - [X86] When iselling (x << C1) and/or/xor C2 as (x and/or/xor (C2>>C1)) << C1, go through the isel table instead of manually selecting.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 26 21:45:58 PDT 2019


Author: ctopper
Date: Tue Mar 26 21:45:58 2019
New Revision: 357049

URL: http://llvm.org/viewvc/llvm-project?rev=357049&view=rev
Log:
[X86] When iselling (x << C1) and/or/xor C2 as (x and/or/xor (C2>>C1)) << C1, go through the isel table instead of manually selecting.

Previously we manually selected the AND/OR/XOR with immediate and the SHL(or ADD if the shift is 1). But this was missing out on the opportunity to use a 64 bit AND with a 32-bit immediate and possibly other isel tricks we have built into the tables.

Instead, insert the new nodes into the DAG using insertDAGNode and allow them each to be selected through the normal table.

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=357049&r1=357048&r2=357049&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Tue Mar 26 21:45:58 2019
@@ -3507,7 +3507,6 @@ void X86DAGToDAGISel::Select(SDNode *Nod
     if (Opcode != ISD::AND && (Val & RemovedBitsMask) != 0)
       break;
 
-    unsigned ShlOp, AddOp, Op;
     MVT CstVT = NVT;
 
     // Check the minimum bitwidth for the new constant.
@@ -3523,45 +3522,15 @@ void X86DAGToDAGISel::Select(SDNode *Nod
     if (NVT == CstVT)
       break;
 
-    switch (NVT.SimpleTy) {
-    default: llvm_unreachable("Unsupported VT!");
-    case MVT::i32:
-      assert(CstVT == MVT::i8);
-      ShlOp = X86::SHL32ri;
-      AddOp = X86::ADD32rr;
-
-      switch (Opcode) {
-      default: llvm_unreachable("Impossible opcode");
-      case ISD::AND: Op = X86::AND32ri8; break;
-      case ISD::OR:  Op =  X86::OR32ri8; break;
-      case ISD::XOR: Op = X86::XOR32ri8; break;
-      }
-      break;
-    case MVT::i64:
-      assert(CstVT == MVT::i8 || CstVT == MVT::i32);
-      ShlOp = X86::SHL64ri;
-      AddOp = X86::ADD64rr;
-
-      switch (Opcode) {
-      default: llvm_unreachable("Impossible opcode");
-      case ISD::AND: Op = CstVT==MVT::i8? X86::AND64ri8 : X86::AND64ri32; break;
-      case ISD::OR:  Op = CstVT==MVT::i8?  X86::OR64ri8 :  X86::OR64ri32; break;
-      case ISD::XOR: Op = CstVT==MVT::i8? X86::XOR64ri8 : X86::XOR64ri32; break;
-      }
-      break;
-    }
-
-    // Emit the smaller op and the shift.
-    // Even though we shrink the constant, the VT should match the operation VT.
-    SDValue NewCst = CurDAG->getTargetConstant(Val >> ShlVal, dl, NVT);
-    SDNode *New = CurDAG->getMachineNode(Op, dl, NVT, MVT::i32,
-                                         N0->getOperand(0), NewCst);
-    if (ShlVal == 1)
-      CurDAG->SelectNodeTo(Node, AddOp, NVT, MVT::i32, SDValue(New, 0),
-                           SDValue(New, 0));
-    else
-      CurDAG->SelectNodeTo(Node, ShlOp, NVT, MVT::i32, SDValue(New, 0),
-                           getI8Imm(ShlVal, dl));
+    SDValue NewCst = CurDAG->getConstant(Val >> ShlVal, dl, NVT);
+    insertDAGNode(*CurDAG, SDValue(Node, 0), NewCst);
+    SDValue NewBinOp = CurDAG->getNode(Opcode, dl, NVT, N0->getOperand(0),
+                                       NewCst);
+    insertDAGNode(*CurDAG, SDValue(Node, 0), NewBinOp);
+    SDValue NewSHL = CurDAG->getNode(ISD::SHL, dl, NVT, NewBinOp,
+                                     N0->getOperand(1));
+    ReplaceNode(Node, NewSHL.getNode());
+    SelectCode(NewSHL.getNode());
     return;
   }
   case X86ISD::SMUL:

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=357049&r1=357048&r2=357049&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/narrow-shl-cst.ll (original)
+++ llvm/trunk/test/CodeGen/X86/narrow-shl-cst.ll Tue Mar 26 21:45:58 2019
@@ -42,7 +42,7 @@ define i64 @test4(i64 %x) nounwind {
 ; CHECK-LABEL: test4:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    movq %rdi, %rax
-; CHECK-NEXT:    andq $241, %rax
+; CHECK-NEXT:    andl $241, %eax
 ; CHECK-NEXT:    shlq $40, %rax
 ; CHECK-NEXT:    retq
   %and = shl i64 %x, 40
@@ -54,7 +54,7 @@ define i64 @test5(i64 %x) nounwind {
 ; CHECK-LABEL: test5:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    movq %rdi, %rax
-; CHECK-NEXT:    andq $31, %rax
+; CHECK-NEXT:    andl $31, %eax
 ; CHECK-NEXT:    shlq $40, %rax
 ; CHECK-NEXT:    retq
   %and = shl i64 %x, 40
@@ -153,7 +153,7 @@ define i64 @test13(i64 %x, i64* %y) noun
 ; CHECK-LABEL: test13:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    movq %rdi, %rax
-; CHECK-NEXT:    andq $127, %rax
+; CHECK-NEXT:    andl $127, %eax
 ; CHECK-NEXT:    addq %rax, %rax
 ; CHECK-NEXT:    movq %rax, (%rsi)
 ; CHECK-NEXT:    retq




More information about the llvm-commits mailing list