[llvm] 0fbe71e - [RISCV] Use hasAllWUsers to recover ANDI.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 29 14:16:53 PDT 2022


Author: Craig Topper
Date: 2022-08-29T14:11:09-07:00
New Revision: 0fbe71e91f44034bdd3f0df4183951f8af1ef958

URL: https://github.com/llvm/llvm-project/commit/0fbe71e91f44034bdd3f0df4183951f8af1ef958
DIFF: https://github.com/llvm/llvm-project/commit/0fbe71e91f44034bdd3f0df4183951f8af1ef958.diff

LOG: [RISCV] Use hasAllWUsers to recover ANDI.

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.

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
    llvm/lib/Target/RISCV/RISCVInstrInfo.td
    llvm/test/CodeGen/RISCV/rv64i-demanded-bits.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 262c870cd3e8..14103857df66 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -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 ||

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 404d86e64fe8..9c28881375c5 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -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
@@ -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>;

diff  --git a/llvm/test/CodeGen/RISCV/rv64i-demanded-bits.ll b/llvm/test/CodeGen/RISCV/rv64i-demanded-bits.ll
index b6f64daaf442..a00510123659 100644
--- a/llvm/test/CodeGen/RISCV/rv64i-demanded-bits.ll
+++ b/llvm/test/CodeGen/RISCV/rv64i-demanded-bits.ll
@@ -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


        


More information about the llvm-commits mailing list