mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-10-09 20:34:54 +00:00
[DAGCombine] fold (X >>?,exact C1) << C2 --> X << (C2-C1)
Instcombine also does this but many opportunities only become visible after GEPs are lowered. llvm-svn: 240787
This commit is contained in:
parent
a17cbff2f6
commit
07e70b4fa4
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user