Skip to content

Commit 16b362e

Browse files
committed
[SelectionDAG][RISCV] Preserve nneg flag when folding (trunc (zext X))->(zext X).
If X is known non-negative, that's still true if we fold the truncate to create a smaller zext. In the 128 tests, SelectionDAGBuilder agressively truncates the zext nneg to i64 to match getShiftAmountTy. If we don't preserve the nneg we can't see that the shift amount argument be signext mean we don't need to do any extension.
1 parent ac62dbf commit 16b362e

File tree

3 files changed

+42
-38
lines changed

3 files changed

+42
-38
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15740,8 +15740,12 @@ SDValue DAGCombiner::visitTRUNCATE(SDNode *N) {
1574015740
N0.getOpcode() == ISD::SIGN_EXTEND ||
1574115741
N0.getOpcode() == ISD::ANY_EXTEND) {
1574215742
// if the source is smaller than the dest, we still need an extend.
15743-
if (N0.getOperand(0).getValueType().bitsLT(VT))
15744-
return DAG.getNode(N0.getOpcode(), DL, VT, N0.getOperand(0));
15743+
if (N0.getOperand(0).getValueType().bitsLT(VT)) {
15744+
SDNodeFlags Flags;
15745+
if (N0.getOpcode() == ISD::ZERO_EXTEND)
15746+
Flags.setNonNeg(N0->getFlags().hasNonNeg());
15747+
return DAG.getNode(N0.getOpcode(), DL, VT, N0.getOperand(0), Flags);
15748+
}
1574515749
// if the source is larger than the dest, than we just need the truncate.
1574615750
if (N0.getOperand(0).getValueType().bitsGT(VT))
1574715751
return DAG.getNode(ISD::TRUNCATE, DL, VT, N0.getOperand(0));

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6474,8 +6474,12 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
64746474
OpOpcode == ISD::ANY_EXTEND) {
64756475
// If the source is smaller than the dest, we still need an extend.
64766476
if (N1.getOperand(0).getValueType().getScalarType().bitsLT(
6477-
VT.getScalarType()))
6478-
return getNode(OpOpcode, DL, VT, N1.getOperand(0));
6477+
VT.getScalarType())) {
6478+
SDNodeFlags Flags;
6479+
if (OpOpcode == ISD::ZERO_EXTEND)
6480+
Flags.setNonNeg(N1->getFlags().hasNonNeg());
6481+
return getNode(OpOpcode, DL, VT, N1.getOperand(0), Flags);
6482+
}
64796483
if (N1.getOperand(0).getValueType().bitsGT(VT))
64806484
return getNode(ISD::TRUNCATE, DL, VT, N1.getOperand(0));
64816485
return N1.getOperand(0);

llvm/test/CodeGen/RISCV/shifts.ll

Lines changed: 30 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -620,23 +620,21 @@ define i128 @lshr128_shamt32(i128 %a, i32 signext %b) nounwind {
620620
;
621621
; RV64I-LABEL: lshr128_shamt32:
622622
; RV64I: # %bb.0:
623-
; RV64I-NEXT: slli a4, a2, 32
624-
; RV64I-NEXT: srli a4, a4, 32
625-
; RV64I-NEXT: addi a3, a4, -64
626-
; RV64I-NEXT: bltz a3, .LBB14_2
623+
; RV64I-NEXT: addi a4, a2, -64
624+
; RV64I-NEXT: srl a3, a1, a2
625+
; RV64I-NEXT: bltz a4, .LBB14_2
627626
; RV64I-NEXT: # %bb.1:
628-
; RV64I-NEXT: srl a0, a1, a4
627+
; RV64I-NEXT: mv a0, a3
629628
; RV64I-NEXT: j .LBB14_3
630629
; RV64I-NEXT: .LBB14_2:
631630
; RV64I-NEXT: srl a0, a0, a2
632-
; RV64I-NEXT: slli a5, a1, 1
633-
; RV64I-NEXT: not a4, a4
634-
; RV64I-NEXT: sll a4, a5, a4
635-
; RV64I-NEXT: or a0, a0, a4
631+
; RV64I-NEXT: not a2, a2
632+
; RV64I-NEXT: slli a1, a1, 1
633+
; RV64I-NEXT: sll a1, a1, a2
634+
; RV64I-NEXT: or a0, a0, a1
636635
; RV64I-NEXT: .LBB14_3:
637-
; RV64I-NEXT: srl a1, a1, a2
638-
; RV64I-NEXT: srai a3, a3, 63
639-
; RV64I-NEXT: and a1, a3, a1
636+
; RV64I-NEXT: srai a1, a4, 63
637+
; RV64I-NEXT: and a1, a1, a3
640638
; RV64I-NEXT: ret
641639
%zext = zext nneg i32 %b to i128
642640
%1 = lshr i128 %a, %zext
@@ -692,21 +690,21 @@ define i128 @ashr128_shamt32(i128 %a, i32 signext %b) nounwind {
692690
;
693691
; RV64I-LABEL: ashr128_shamt32:
694692
; RV64I: # %bb.0:
695-
; RV64I-NEXT: slli a3, a2, 32
696-
; RV64I-NEXT: srli a3, a3, 32
697-
; RV64I-NEXT: addi a4, a3, -64
693+
; RV64I-NEXT: mv a3, a1
694+
; RV64I-NEXT: addi a4, a2, -64
695+
; RV64I-NEXT: sra a1, a1, a2
698696
; RV64I-NEXT: bltz a4, .LBB15_2
699697
; RV64I-NEXT: # %bb.1:
700-
; RV64I-NEXT: sra a0, a1, a3
701-
; RV64I-NEXT: srai a1, a1, 63
698+
; RV64I-NEXT: srai a3, a3, 63
699+
; RV64I-NEXT: mv a0, a1
700+
; RV64I-NEXT: mv a1, a3
702701
; RV64I-NEXT: ret
703702
; RV64I-NEXT: .LBB15_2:
704703
; RV64I-NEXT: srl a0, a0, a2
705-
; RV64I-NEXT: slli a4, a1, 1
706-
; RV64I-NEXT: not a3, a3
707-
; RV64I-NEXT: sll a3, a4, a3
708-
; RV64I-NEXT: or a0, a0, a3
709-
; RV64I-NEXT: sra a1, a1, a2
704+
; RV64I-NEXT: not a2, a2
705+
; RV64I-NEXT: slli a3, a3, 1
706+
; RV64I-NEXT: sll a2, a3, a2
707+
; RV64I-NEXT: or a0, a0, a2
710708
; RV64I-NEXT: ret
711709
%zext = zext nneg i32 %b to i128
712710
%1 = ashr i128 %a, %zext
@@ -761,23 +759,21 @@ define i128 @shl128_shamt32(i128 %a, i32 signext %b) nounwind {
761759
;
762760
; RV64I-LABEL: shl128_shamt32:
763761
; RV64I: # %bb.0:
764-
; RV64I-NEXT: slli a4, a2, 32
765-
; RV64I-NEXT: srli a4, a4, 32
766-
; RV64I-NEXT: addi a3, a4, -64
767-
; RV64I-NEXT: bltz a3, .LBB16_2
762+
; RV64I-NEXT: addi a4, a2, -64
763+
; RV64I-NEXT: sll a3, a0, a2
764+
; RV64I-NEXT: bltz a4, .LBB16_2
768765
; RV64I-NEXT: # %bb.1:
769-
; RV64I-NEXT: sll a1, a0, a4
766+
; RV64I-NEXT: mv a1, a3
770767
; RV64I-NEXT: j .LBB16_3
771768
; RV64I-NEXT: .LBB16_2:
772769
; RV64I-NEXT: sll a1, a1, a2
773-
; RV64I-NEXT: srli a5, a0, 1
774-
; RV64I-NEXT: not a4, a4
775-
; RV64I-NEXT: srl a4, a5, a4
776-
; RV64I-NEXT: or a1, a1, a4
770+
; RV64I-NEXT: not a2, a2
771+
; RV64I-NEXT: srli a0, a0, 1
772+
; RV64I-NEXT: srl a0, a0, a2
773+
; RV64I-NEXT: or a1, a1, a0
777774
; RV64I-NEXT: .LBB16_3:
778-
; RV64I-NEXT: sll a0, a0, a2
779-
; RV64I-NEXT: srai a3, a3, 63
780-
; RV64I-NEXT: and a0, a3, a0
775+
; RV64I-NEXT: srai a0, a4, 63
776+
; RV64I-NEXT: and a0, a0, a3
781777
; RV64I-NEXT: ret
782778
%zext = zext nneg i32 %b to i128
783779
%1 = shl i128 %a, %zext

0 commit comments

Comments
 (0)