@@ -80,28 +80,52 @@ class RISCVSelectionDAGTest : public testing::Test {
8080
8181// / SRLW: Logical Shift Right
8282TEST_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