Skip to content

Commit 539724b

Browse files
committed
[DAG] Fold patterm for SRL
fold (srl (or x, (shl (zext y), c1), c1) -> (or (srl x, c1), (zext y)) for c1 <= leadingzeros(zext(y))
1 parent 0b2ab11 commit 539724b

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10979,6 +10979,39 @@ SDValue DAGCombiner::visitSRL(SDNode *N) {
1097910979
return DAG.getNode(ISD::SRL, DL, VT, N0, NewOp1);
1098010980
}
1098110981

10982+
// fold (srl (or x, (shl (zext y), c1)), c1) -> (or (srl x, c1), (zext y))
10983+
// c1 <= leadingzeros(zext(y))
10984+
if (N1C && (N0.getOpcode() == ISD::OR || N0.getOpcode() == ISD::AND ||
10985+
N0.getOpcode() == ISD::XOR)) {
10986+
SDValue lhs = N0.getOperand(0);
10987+
SDValue rhs = N0.getOperand(1);
10988+
SDValue shl;
10989+
SDValue other;
10990+
if (lhs.getOpcode() == ISD::SHL) {
10991+
shl = lhs;
10992+
other = rhs;
10993+
} else if (rhs.getOpcode() == ISD::SHL) {
10994+
shl = rhs;
10995+
other = lhs;
10996+
}
10997+
if (shl.getNode()) {
10998+
if (shl.getOperand(1).getNode() == N1C) {
10999+
SDValue zext = shl.getOperand(0);
11000+
if (zext.getOpcode() == ISD::ZERO_EXTEND) {
11001+
unsigned numLeadingZeros =
11002+
zext.getValueType().getSizeInBits() -
11003+
zext.getOperand(0).getValueType().getSizeInBits();
11004+
if (N1C->getZExtValue() <= numLeadingZeros) {
11005+
return DAG.getNode(
11006+
N0.getOpcode(), SDLoc(N0), VT,
11007+
DAG.getNode(ISD::SRL, SDLoc(N0), VT, other, SDValue(N1C, 0)),
11008+
zext);
11009+
}
11010+
}
11011+
}
11012+
}
11013+
}
11014+
1098211015
// fold operands of srl based on knowledge that the low bits are not
1098311016
// demanded.
1098411017
if (SimplifyDemandedBits(SDValue(N, 0)))

llvm/test/CodeGen/NVPTX/shift-opt.ll

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
; RUN: llc < %s -mtriple=nvptx64 | FileCheck %s
2+
3+
define i64 @test1(i64 %x, i32 %y) {
4+
;
5+
; srl (or (x, shl(zext(y),c1)),c1) -> or(srl(x,c1), zext(y))
6+
; c1 <= leadingzeros(zext(y))
7+
;
8+
; CHECK-LABEL: test1
9+
; CHECK: ld.param.u64 %[[X:rd[0-9]+]], [test1_param_0];
10+
; CHECK: ld.param.u32 %[[Y:rd[0-9]+]], [test1_param_1];
11+
; CHECK: shr.u64 %[[SHR:rd[0-9]+]], %[[X]], 5;
12+
; CHECK: or.b64 %[[OR:rd[0-9]+]], %[[SHR]], %[[Y]];
13+
; CHECK: st.param.b64 [func_retval0], %[[OR]];
14+
;
15+
%ext = zext i32 %y to i64
16+
%shl = shl i64 %ext, 5
17+
%or = or i64 %x, %shl
18+
%srl = lshr i64 %or, 5
19+
ret i64 %srl
20+
}
21+
22+
define i64 @test2(i64 %x, i32 %y) {
23+
;
24+
; srl (or (x, shl(zext(y),c1)),c1) -> or(srl(x,c1), zext(y))
25+
; c1 > leadingzeros(zext(y)).
26+
;
27+
; CHECK-LABEL: test2
28+
; CHECK: ld.param.u64 %[[X:rd[0-9]+]], [test2_param_0];
29+
; CHECK: ld.param.u32 %[[Y:rd[0-9]+]], [test2_param_1];
30+
; CHECK: shl.b64 %[[SHL:rd[0-9]+]], %[[Y]], 33;
31+
; CHECK: or.b64 %[[OR:rd[0-9]+]], %[[X]], %[[SHL]];
32+
; CHECK: shr.u64 %[[SHR:rd[0-9]+]], %[[OR]], 33;
33+
; CHECK: st.param.b64 [func_retval0], %[[SHR]];
34+
;
35+
%ext = zext i32 %y to i64
36+
%shl = shl i64 %ext, 33
37+
%or = or i64 %x, %shl
38+
%srl = lshr i64 %or, 33
39+
ret i64 %srl
40+
}

0 commit comments

Comments
 (0)