Skip to content

Commit 6ea2ccd

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]> Signed-off-by: Luke Quinn <[email protected]>
1 parent 91ce4aa commit 6ea2ccd

File tree

10 files changed

+226
-167
lines changed

10 files changed

+226
-167
lines changed

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

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,6 @@ class RISCVInstructionSelector : public InstructionSelector {
6161

6262
bool hasAllNBitUsers(const MachineInstr &MI, unsigned Bits,
6363
const unsigned Depth = 0) const;
64-
bool hasAllBUsers(const MachineInstr &MI) const {
65-
return hasAllNBitUsers(MI, 8);
66-
}
6764
bool hasAllHUsers(const MachineInstr &MI) const {
6865
return hasAllNBitUsers(MI, 16);
6966
}
@@ -198,9 +195,78 @@ RISCVInstructionSelector::RISCVInstructionSelector(
198195
{
199196
}
200197

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

205271
InstructionSelector::ComplexRendererFns
206272
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)