Skip to content

Commit 04eb8c3

Browse files
committed
[RISCV] re-write DAG generation based on actual DAG output
Signed-off-by: Shreeyash Pandey <[email protected]>
1 parent f3833cd commit 04eb8c3

File tree

1 file changed

+41
-17
lines changed

1 file changed

+41
-17
lines changed

llvm/unittests/Target/RISCV/RISCVSelectionDAGTest.cpp

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -80,28 +80,52 @@ class RISCVSelectionDAGTest : public testing::Test {
8080

8181
/// SRLW: Logical Shift Right
8282
TEST_F(RISCVSelectionDAGTest, computeKnownBits_SRLW) {
83-
// Following DAG is created from this IR snippet:
83+
// Given the following IR snippet:
84+
// define i64 @f(i32 %x, i32 %y) {
85+
// %a = and i32 %x, 2147483647 ; zeros the MSB for %x
86+
// %b = lshr i32 %a, %y
87+
// %c = zext i32 %b to i64 ; makes the most significant 32 bits 0
88+
// ret i64 %c
89+
// }
90+
// The Optimized SelectionDAG as show by llc -mtriple="riscv64" -debug-only=isel-dump
91+
// is:
92+
// t0: ch,glue = EntryToken
93+
// t2: i64,ch = CopyFromReg t0, Register:i64 %0
94+
// t18: i64 = and t2, Constant:i64<2147483647>
95+
// t4: i64,ch = CopyFromReg t0, Register:i64 %1
96+
// t20: i64 = RISCVISD::SRLW t18, t4
97+
// t22: i64 = and t20, Constant:i64<4294967295>
98+
// t13: ch,glue = CopyToReg t0, Register:i64 $x10, t22
99+
// t14: ch = RISCVISD::RET_GLUE t13, Register:i64 $x10, t13:1
84100
//
85-
// define i64 @f(i32 %x, i32 %y) {
86-
// %a = and i32 %x, 2147483647 ; zeros the MSB for %x
87-
// %b = lshr i32 %a, %y
88-
// %c = zext i32 %b to i64 ; makes the most significant 32 bits 0
89-
// ret i64 %c
90-
// }
101+
// The DAG created below is derived from this
91102
SDLoc Loc;
92-
auto IntVT = EVT::getIntegerVT(Context, 32);
93103
auto Int64VT = EVT::getIntegerVT(Context, 64);
94-
auto Px = DAG->getRegister(0, IntVT);
95-
auto Py = DAG->getConstant(2147483647, Loc, IntVT);
96-
auto N1 = DAG->getNode(ISD::AND, Loc, IntVT, Px, Py);
104+
auto Px = DAG->getRegister(0, Int64VT);
105+
auto Py = DAG->getConstant(2147483647, Loc, Int64VT);
106+
auto N1 = DAG->getNode(ISD::AND, Loc, Int64VT, Px, Py);
97107
auto Qx = DAG->getRegister(0, Int64VT);
98108
auto N2 = DAG->getNode(RISCVISD::SRLW, Loc, Int64VT, N1, Qx);
99-
auto N3 = DAG->getNode(ISD::ZERO_EXTEND, Loc, Int64VT, N2);
100-
// N1 = 0???????????????????????????????
101-
// N2 = 0???????????????????????????????
102-
// N3 = 000000000000000000000000000000000???????????????????????????????
103-
// After zero extend, we expect 33 most significant zeros to be known:
104-
// 32 from sign extension and 1 from AND operation
109+
auto Py2 = DAG->getConstant(4294967295, Loc, Int64VT);
110+
auto N3 = DAG->getNode(ISD::AND, Loc, Int64VT, N2, Py2);
111+
// N1 = Px & 0x7FFFFFFF
112+
// The first AND ensures that the input to the shift has bit 31 cleared.
113+
// This means bits [63:31] of N1 are known to be zero.
114+
//
115+
// N2 = SRLW N1, Qx
116+
// SRLW performs a 32-bit logical right shift and then sign-extends the
117+
// 32-bit result to 64 bits. Because we know N1's bit 31 is 0, the
118+
// 32-bit result of the shift will also have its sign bit (bit 31) as 0.
119+
// Therefore, the sign-extension is guaranteed to be a zero-extension.
120+
//
121+
// N3 = N2 & 0xFFFFFFFF
122+
// This second AND is part of the canonical pattern to clear the upper
123+
// 32 bits, explicitly performing the zero-extension. From a KnownBits
124+
// perspective, it's redundant, as N2's upper bits are already known zero.
125+
//
126+
// As a result, for N3, we know the upper 32 bits are zero (from the effective
127+
// zero-extension) and we also know bit 31 is zero (from the initial AND).
128+
// This gives us 33 known most-significant zero bits.
105129
KnownBits Known = DAG->computeKnownBits(N3);
106130
EXPECT_EQ(Known.Zero, APInt(64, -2147483648));
107131
EXPECT_EQ(Known.One, APInt(64, 0));

0 commit comments

Comments
 (0)