[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