[llvm] r240787 - [DAGCombine] fold (X >>?, exact C1) << C2 --> X << (C2-C1)

Benjamin Kramer benny.kra at googlemail.com
Fri Jun 26 07:51:36 PDT 2015


Author: d0k
Date: Fri Jun 26 09:51:36 2015
New Revision: 240787

URL: http://llvm.org/viewvc/llvm-project?rev=240787&view=rev
Log:
[DAGCombine] fold (X >>?,exact C1) << C2 --> X << (C2-C1)

Instcombine also does this but many opportunities only become visible
after GEPs are lowered.

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
    llvm/trunk/test/CodeGen/X86/shift-combine.ll

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=240787&r1=240786&r2=240787&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Fri Jun 26 09:51:36 2015
@@ -4362,6 +4362,22 @@ SDValue DAGCombiner::visitSHL(SDNode *N)
     }
   }
 
+  // fold (shl (sr[la] exact X,  C1), C2) -> (shl    X, (C2-C1)) if C1 <= C2
+  // fold (shl (sr[la] exact X,  C1), C2) -> (sr[la] X, (C2-C1)) if C1  > C2
+  if (N1C && (N0.getOpcode() == ISD::SRL || N0.getOpcode() == ISD::SRA) &&
+      cast<BinaryWithFlagsSDNode>(N0)->Flags.hasExact()) {
+    if (ConstantSDNode *N0C1 = isConstOrConstSplat(N0.getOperand(1))) {
+      uint64_t C1 = N0C1->getZExtValue();
+      uint64_t C2 = N1C->getZExtValue();
+      SDLoc DL(N);
+      if (C1 <= C2)
+        return DAG.getNode(ISD::SHL, DL, VT, N0.getOperand(0),
+                           DAG.getConstant(C2 - C1, DL, N1.getValueType()));
+      return DAG.getNode(N0.getOpcode(), DL, VT, N0.getOperand(0),
+                         DAG.getConstant(C1 - C2, DL, N1.getValueType()));
+    }
+  }
+
   // fold (shl (srl x, c1), c2) -> (and (shl x, (sub c2, c1), MASK) or
   //                               (and (srl x, (sub c1, c2), MASK)
   // Only fold this if the inner shift has no other uses -- if it does, folding

Modified: llvm/trunk/test/CodeGen/X86/shift-combine.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/shift-combine.ll?rev=240787&r1=240786&r2=240787&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/shift-combine.ll (original)
+++ llvm/trunk/test/CodeGen/X86/shift-combine.ll Fri Jun 26 09:51:36 2015
@@ -17,3 +17,52 @@ entry:
   ret i32 %tmp5
 }
 
+define i32* @test_exact1(i32 %a, i32 %b, i32* %x)  {
+; CHECK-LABEL: test_exact1:
+; CHECK: sarl %
+
+  %sub = sub i32 %b, %a
+  %shr = ashr exact i32 %sub, 3
+  %gep = getelementptr inbounds i32, i32* %x, i32 %shr
+  ret i32* %gep
+}
+
+define i32* @test_exact2(i32 %a, i32 %b, i32* %x)  {
+; CHECK-LABEL: test_exact2:
+; CHECK: sarl %
+
+  %sub = sub i32 %b, %a
+  %shr = ashr exact i32 %sub, 3
+  %gep = getelementptr inbounds i32, i32* %x, i32 %shr
+  ret i32* %gep
+}
+
+define i32* @test_exact4(i32 %a, i32 %b, i32* %x)  {
+; CHECK-LABEL: test_exact4:
+; CHECK: shrl %
+
+  %sub = sub i32 %b, %a
+  %shr = lshr exact i32 %sub, 3
+  %gep = getelementptr inbounds i32, i32* %x, i32 %shr
+  ret i32* %gep
+}
+
+define i32* @test_exact5(i32 %a, i32 %b, i32* %x)  {
+; CHECK-LABEL: test_exact5:
+; CHECK: shrl %
+
+  %sub = sub i32 %b, %a
+  %shr = lshr exact i32 %sub, 3
+  %gep = getelementptr inbounds i32, i32* %x, i32 %shr
+  ret i32* %gep
+}
+
+define i32* @test_exact6(i32 %a, i32 %b, i32* %x)  {
+; CHECK-LABEL: test_exact6:
+; CHECK-NOT: shrl
+
+  %sub = sub i32 %b, %a
+  %shr = lshr exact i32 %sub, 2
+  %gep = getelementptr inbounds i32, i32* %x, i32 %shr
+  ret i32* %gep
+}





More information about the llvm-commits mailing list