Skip to content

Commit 81ceb00

Browse files
committed
[RISCV] Add hasAllNBitUsers Functional change, change allows for generation of packw instructions along with other generic instructions with narrow w types. The Optimization pass was reduced from ISEL for testing coverage
Signed-off-by: Luke Quinn <[email protected]>
1 parent 91ce4aa commit 81ceb00

File tree

10 files changed

+226
-164
lines changed

10 files changed

+226
-164
lines changed

llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,78 @@ RISCVInstructionSelector::RISCVInstructionSelector(
198198
{
199199
}
200200

201-
bool RISCVInstructionSelector::hasAllNBitUsers(const MachineInstr &MI, unsigned Bits, const unsigned Depth) const {
201+
// Mimics optimizations in ISel and RISCVOptWInst Pass
202+
bool RISCVInstructionSelector::hasAllNBitUsers(const MachineInstr &MI,
203+
unsigned Bits,
204+
const unsigned Depth) const {
205+
206+
assert((MI.getOpcode() == TargetOpcode::G_ADD ||
207+
MI.getOpcode() == TargetOpcode::G_SUB ||
208+
MI.getOpcode() == TargetOpcode::G_MUL ||
209+
MI.getOpcode() == TargetOpcode::G_SHL ||
210+
MI.getOpcode() == TargetOpcode::G_LSHR ||
211+
MI.getOpcode() == TargetOpcode::G_AND ||
212+
MI.getOpcode() == TargetOpcode::G_OR ||
213+
MI.getOpcode() == TargetOpcode::G_XOR ||
214+
MI.getOpcode() == TargetOpcode::G_SEXT_INREG || Depth != 0) &&
215+
"Unexpected opcode");
216+
217+
if (Depth >= RISCVInstructionSelector::MaxRecursionDepth)
202218
return false;
203-
};
219+
220+
auto DestReg = MI.getOperand(0).getReg();
221+
for (auto &UserOp : MRI->use_nodbg_operands(DestReg)) {
222+
assert(UserOp.getParent() && "UserOp must have a parent");
223+
const MachineInstr &UserMI = *UserOp.getParent();
224+
unsigned OpIdx = UserOp.getOperandNo();
225+
226+
switch (UserMI.getOpcode()) {
227+
default:
228+
return false;
229+
case RISCV::ADDW:
230+
case RISCV::ADDIW:
231+
case RISCV::SUBW:
232+
if (Bits >= 32)
233+
break;
234+
return false;
235+
case RISCV::SLL:
236+
case RISCV::SRA:
237+
case RISCV::SRL:
238+
// Shift amount operands only use log2(Xlen) bits.
239+
if (OpIdx == 2 && Bits >= Log2_32(Subtarget->getXLen()))
240+
break;
241+
return false;
242+
case RISCV::SLLI:
243+
// SLLI only uses the lower (XLen - ShAmt) bits.
244+
if (Bits >= Subtarget->getXLen() - UserMI.getOperand(2).getImm())
245+
break;
246+
return false;
247+
case RISCV::ANDI:
248+
if (Bits >= (unsigned)llvm::bit_width<uint64_t>(
249+
(uint64_t)UserMI.getOperand(2).getImm()))
250+
break;
251+
goto RecCheck;
252+
case RISCV::AND:
253+
case RISCV::OR:
254+
case RISCV::XOR:
255+
RecCheck:
256+
if (hasAllNBitUsers(UserMI, Bits, Depth + 1))
257+
break;
258+
return false;
259+
case RISCV::SRLI: {
260+
unsigned ShAmt = UserMI.getOperand(2).getImm();
261+
// If we are shifting right by less than Bits, and users don't demand any
262+
// bits that were shifted into [Bits-1:0], then we can consider this as an
263+
// N-Bit user.
264+
if (Bits > ShAmt && hasAllNBitUsers(UserMI, Bits - ShAmt, Depth + 1))
265+
break;
266+
return false;
267+
}
268+
}
269+
}
270+
271+
return true;
272+
}
204273

205274
InstructionSelector::ComplexRendererFns
206275
RISCVInstructionSelector::selectShiftMask(MachineOperand &Root,

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1950,14 +1950,14 @@ class binop_allhusers<SDPatternOperator operator>
19501950
(XLenVT (operator node:$lhs, node:$rhs)), [{
19511951
return hasAllHUsers(Node);
19521952
}]> {
1953-
let GISelPredicateCode = [{ return hasAllHUsers(MI); }];
1953+
let GISelPredicateCode = [{ return hasAllHUsers(MI); }];
19541954
}
19551955

19561956
// PatFrag to allow ADDW/SUBW/MULW/SLLW to be selected from i64 add/sub/mul/shl
19571957
// if only the lower 32 bits of their result is used.
19581958
class binop_allwusers<SDPatternOperator operator>
1959-
: PatFrag<(ops node:$lhs, node:$rhs),
1960-
(i64 (operator node:$lhs, node:$rhs)), [{
1959+
: PatFrag<(ops node:$lhs, node:$rhs), (i64 (operator node:$lhs, node:$rhs)),
1960+
[{
19611961
return hasAllWUsers(Node);
19621962
}]> {
19631963
let GISelPredicateCode = [{ return hasAllWUsers(MI); }];

llvm/test/CodeGen/RISCV/GlobalISel/combine.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ define i32 @constant_to_rhs(i32 %x) {
2020
; RV64-O0: # %bb.0:
2121
; RV64-O0-NEXT: mv a1, a0
2222
; RV64-O0-NEXT: li a0, 1
23-
; RV64-O0-NEXT: add a0, a0, a1
23+
; RV64-O0-NEXT: addw a0, a0, a1
2424
; RV64-O0-NEXT: sext.w a0, a0
2525
; RV64-O0-NEXT: ret
2626
;

llvm/test/CodeGen/RISCV/GlobalISel/div-by-constant.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ define i32 @udiv_constant_add(i32 %a) nounwind {
6666
; RV64IM-NEXT: srli a2, a2, 32
6767
; RV64IM-NEXT: mul a1, a2, a1
6868
; RV64IM-NEXT: srli a1, a1, 32
69-
; RV64IM-NEXT: sub a0, a0, a1
69+
; RV64IM-NEXT: subw a0, a0, a1
7070
; RV64IM-NEXT: srliw a0, a0, 1
7171
; RV64IM-NEXT: add a0, a0, a1
7272
; RV64IM-NEXT: srliw a0, a0, 2
@@ -79,7 +79,7 @@ define i32 @udiv_constant_add(i32 %a) nounwind {
7979
; RV64IMZB-NEXT: zext.w a2, a0
8080
; RV64IMZB-NEXT: mul a1, a2, a1
8181
; RV64IMZB-NEXT: srli a1, a1, 32
82-
; RV64IMZB-NEXT: sub a0, a0, a1
82+
; RV64IMZB-NEXT: subw a0, a0, a1
8383
; RV64IMZB-NEXT: srliw a0, a0, 1
8484
; RV64IMZB-NEXT: add a0, a0, a1
8585
; RV64IMZB-NEXT: srliw a0, a0, 2
@@ -265,7 +265,7 @@ define i8 @udiv8_constant_add(i8 %a) nounwind {
265265
; RV64-NEXT: andi a2, a0, 255
266266
; RV64-NEXT: mul a1, a2, a1
267267
; RV64-NEXT: srli a1, a1, 8
268-
; RV64-NEXT: sub a0, a0, a1
268+
; RV64-NEXT: subw a0, a0, a1
269269
; RV64-NEXT: andi a0, a0, 255
270270
; RV64-NEXT: srli a0, a0, 1
271271
; RV64-NEXT: add a0, a0, a1

0 commit comments

Comments
 (0)