Skip to content

Commit 20e6265

Browse files
committed
[RISCV] Improve constant materialization for stores of i16 or i32 negative constants.
DAGCombiner::visitStore can clear the upper bits of constants used by stores. This leads prevents them from being recognized as sign extended negative values making them more expensive to materialize. This patch uses the hasAllNBitUsers method from D107658 to make a negative constant if none of the users care about the upper bits. Reviewed By: luismarques Differential Revision: https://reviews.llvm.org/D108052
1 parent d9ba1a9 commit 20e6265

File tree

4 files changed

+19
-11
lines changed

4 files changed

+19
-11
lines changed

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

+14-3
Original file line numberDiff line numberDiff line change
@@ -459,8 +459,18 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
459459
ReplaceNode(Node, New.getNode());
460460
return;
461461
}
462-
ReplaceNode(Node,
463-
selectImm(CurDAG, DL, ConstNode->getSExtValue(), *Subtarget));
462+
int64_t Imm = ConstNode->getSExtValue();
463+
// If the upper XLen-16 bits are not used, try to convert this to a simm12
464+
// by sign extending bit 15.
465+
if (isUInt<16>(Imm) && isInt<12>(SignExtend64(Imm, 16)) &&
466+
hasAllHUsers(Node))
467+
Imm = SignExtend64(Imm, 16);
468+
// If the upper 32-bits are not used try to convert this into a simm32 by
469+
// sign extending bit 32.
470+
if (!isInt<32>(Imm) && isUInt<32>(Imm) && hasAllWUsers(Node))
471+
Imm = SignExtend64(Imm, 32);
472+
473+
ReplaceNode(Node, selectImm(CurDAG, DL, Imm, *Subtarget));
464474
return;
465475
}
466476
case ISD::FrameIndex: {
@@ -1509,7 +1519,8 @@ bool RISCVDAGToDAGISel::selectZExti32(SDValue N, SDValue &Val) {
15091519
// opportunities.
15101520
bool RISCVDAGToDAGISel::hasAllNBitUsers(SDNode *Node, unsigned Bits) const {
15111521
assert((Node->getOpcode() == ISD::ADD || Node->getOpcode() == ISD::SUB ||
1512-
Node->getOpcode() == ISD::MUL || Node->getOpcode() == ISD::SHL) &&
1522+
Node->getOpcode() == ISD::MUL || Node->getOpcode() == ISD::SHL ||
1523+
isa<ConstantSDNode>(Node)) &&
15131524
"Unexpected opcode");
15141525

15151526
for (auto UI = Node->use_begin(), UE = Node->use_end(); UI != UE; ++UI) {

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
5959
bool selectZExti32(SDValue N, SDValue &Val);
6060

6161
bool hasAllNBitUsers(SDNode *Node, unsigned Bits) const;
62+
bool hasAllHUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 16); }
6263
bool hasAllWUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 32); }
6364

6465
bool selectVLOp(SDValue N, SDValue &VL);

llvm/test/CodeGen/RISCV/calling-conv-half.ll

+2-3
Original file line numberDiff line numberDiff line change
@@ -347,9 +347,8 @@ define i32 @caller_half_on_stack() nounwind {
347347
; RV64IF: # %bb.0:
348348
; RV64IF-NEXT: addi sp, sp, -16
349349
; RV64IF-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
350-
; RV64IF-NEXT: addi a0, zero, -183
351-
; RV64IF-NEXT: slli a0, a0, 40
352-
; RV64IF-NEXT: srli t0, a0, 32
350+
; RV64IF-NEXT: lui a0, 1048565
351+
; RV64IF-NEXT: addiw t0, a0, -1792
353352
; RV64IF-NEXT: addi a0, zero, 1
354353
; RV64IF-NEXT: addi a1, zero, 2
355354
; RV64IF-NEXT: addi a2, zero, 3

llvm/test/CodeGen/RISCV/imm.ll

+2-5
Original file line numberDiff line numberDiff line change
@@ -482,15 +482,13 @@ define i64 @imm_2reg_1() nounwind {
482482
define void @imm_store_i16_neg1(i16* %p) nounwind {
483483
; RV32I-LABEL: imm_store_i16_neg1:
484484
; RV32I: # %bb.0:
485-
; RV32I-NEXT: lui a1, 16
486-
; RV32I-NEXT: addi a1, a1, -1
485+
; RV32I-NEXT: addi a1, zero, -1
487486
; RV32I-NEXT: sh a1, 0(a0)
488487
; RV32I-NEXT: ret
489488
;
490489
; RV64I-LABEL: imm_store_i16_neg1:
491490
; RV64I: # %bb.0:
492-
; RV64I-NEXT: lui a1, 16
493-
; RV64I-NEXT: addiw a1, a1, -1
491+
; RV64I-NEXT: addi a1, zero, -1
494492
; RV64I-NEXT: sh a1, 0(a0)
495493
; RV64I-NEXT: ret
496494
store i16 -1, i16* %p
@@ -508,7 +506,6 @@ define void @imm_store_i32_neg1(i32* %p) nounwind {
508506
; RV64I-LABEL: imm_store_i32_neg1:
509507
; RV64I: # %bb.0:
510508
; RV64I-NEXT: addi a1, zero, -1
511-
; RV64I-NEXT: srli a1, a1, 32
512509
; RV64I-NEXT: sw a1, 0(a0)
513510
; RV64I-NEXT: ret
514511
store i32 -1, i32* %p

0 commit comments

Comments
 (0)