Skip to content

Commit

Permalink
[RISCV] Use hasAllWUsers to recover ANDI.
Browse files Browse the repository at this point in the history
SimplifyDemandedBits can 0 the upper bits and targetShrinkDemandedConstant
isn't alway able to recover it.

At least part of that may be because targetShrinkDemandedConstant
only runs in the last DAGCombine. Might be worth seeing what happens
if we move it post type legalization.
  • Loading branch information
topperc committed Aug 29, 2022
1 parent 7c17b0a commit 0fbe71e
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 7 deletions.
2 changes: 1 addition & 1 deletion llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
Expand Up @@ -2218,7 +2218,7 @@ bool RISCVDAGToDAGISel::selectSHXADDOp(SDValue N, unsigned ShAmt,
bool RISCVDAGToDAGISel::hasAllNBitUsers(SDNode *Node, unsigned Bits) const {
assert((Node->getOpcode() == ISD::ADD || Node->getOpcode() == ISD::SUB ||
Node->getOpcode() == ISD::MUL || Node->getOpcode() == ISD::SHL ||
Node->getOpcode() == ISD::SRL ||
Node->getOpcode() == ISD::SRL || Node->getOpcode() == ISD::AND ||
Node->getOpcode() == ISD::SIGN_EXTEND_INREG ||
Node->getOpcode() == RISCVISD::GREV ||
Node->getOpcode() == RISCVISD::GORC ||
Expand Down
16 changes: 16 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.td
Expand Up @@ -1581,6 +1581,16 @@ def sexti32_allwusers : PatFrag<(ops node:$src),
return hasAllWUsers(Node);
}]>;

def ImmSExt32 : SDNodeXForm<imm, [{
return CurDAG->getTargetConstant(SignExtend64<32>(N->getSExtValue()),
SDLoc(N), N->getValueType(0));
}]>;
// Look for constants where the upper 32 bits are 0, but sign extending bit 31
// would be an simm12.
def u32simm12 : ImmLeaf<XLenVT, [{
return isUInt<32>(Imm) && isInt<12>(SignExtend64<32>(Imm));
}], ImmSExt32>;

let Predicates = [IsRV64] in {

/// sext and zext
Expand Down Expand Up @@ -1617,6 +1627,12 @@ def : PatGprImm<binop_allwusers<shl>, SLLIW, uimm5>;
def : Pat<(binop_allwusers<srl> (sext_inreg GPR:$rs1, i32), uimm5:$shamt),
(SRAIW GPR:$rs1, uimm5:$shamt)>;

// Use binop_allwusers to recover immediates that may have been broken by
// SimplifyDemandedBits.
// TODO: This is valid for ADDI/ORI/XORI.
def : Pat<(binop_allwusers<and> GPR:$rs1, u32simm12:$imm),
(ANDI GPR:$rs1, u32simm12:$imm)>;

/// Loads

defm : LdPat<sextloadi32, LW, i64>;
Expand Down
8 changes: 2 additions & 6 deletions llvm/test/CodeGen/RISCV/rv64i-demanded-bits.ll
Expand Up @@ -104,15 +104,11 @@ define void @xor_signbit(ptr nocapture noundef %0) {
; removes the sext_inreg from the path to the store. This prevents
; TargetShrinkDemandedConstant from being able to restore the lost upper bits
; from the and mask to allow andi. ISel is able to recover the lost sext_inreg
; using hasAllWUsers.
; FIXME: Use hasAllWUers to recover the ANDI.
; using hasAllWUsers. We also use hasAllWUsers to recover the ANDI.
define signext i32 @andi_sub_cse(i32 signext %0, i32 signext %1, ptr %2) {
; CHECK-LABEL: andi_sub_cse:
; CHECK: # %bb.0:
; CHECK-NEXT: li a3, 1
; CHECK-NEXT: slli a3, a3, 32
; CHECK-NEXT: addi a3, a3, -8
; CHECK-NEXT: and a0, a0, a3
; CHECK-NEXT: andi a0, a0, -8
; CHECK-NEXT: subw a0, a0, a1
; CHECK-NEXT: sw a0, 0(a2)
; CHECK-NEXT: ret
Expand Down

0 comments on commit 0fbe71e

Please sign in to comment.