Skip to content

Commit 8ed046f

Browse files
committed
[RISCV] Custom type legalize i32 SADDSAT/SSUBSAT without Zbb.
While working on -riscv-experimental-rv64-legal-i32, I noticed this missed optimization in our current codegen. This expands to SADDO/SSUBO+select while still in i32. These will be type legalized individually.
1 parent ae5ed2a commit 8ed046f

File tree

5 files changed

+35
-42
lines changed

5 files changed

+35
-42
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
282282
MVT::i32, Custom);
283283
setOperationAction({ISD::UADDO, ISD::USUBO, ISD::UADDSAT, ISD::USUBSAT},
284284
MVT::i32, Custom);
285+
if (!Subtarget.hasStdExtZbb())
286+
setOperationAction({ISD::SADDSAT, ISD::SSUBSAT}, MVT::i32, Custom);
285287
} else {
286288
setOperationAction(ISD::SSUBO, MVT::i32, Custom);
287289
if (Subtarget.hasStdExtZbb()) {
@@ -11879,6 +11881,13 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
1187911881
Results.push_back(expandAddSubSat(N, DAG));
1188011882
return;
1188111883
}
11884+
case ISD::SADDSAT:
11885+
case ISD::SSUBSAT: {
11886+
assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
11887+
"Unexpected custom legalisation");
11888+
Results.push_back(expandAddSubSat(N, DAG));
11889+
return;
11890+
}
1188211891
case ISD::ABS: {
1188311892
assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
1188411893
"Unexpected custom legalisation");

llvm/test/CodeGen/RISCV/sadd_sat.ll

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,16 @@ define signext i32 @func(i32 signext %x, i32 signext %y) nounwind {
2727
;
2828
; RV64I-LABEL: func:
2929
; RV64I: # %bb.0:
30-
; RV64I-NEXT: add a0, a0, a1
31-
; RV64I-NEXT: lui a1, 524288
32-
; RV64I-NEXT: addiw a2, a1, -1
33-
; RV64I-NEXT: bge a0, a2, .LBB0_3
30+
; RV64I-NEXT: add a2, a0, a1
31+
; RV64I-NEXT: addw a0, a0, a1
32+
; RV64I-NEXT: beq a0, a2, .LBB0_2
3433
; RV64I-NEXT: # %bb.1:
35-
; RV64I-NEXT: bge a1, a0, .LBB0_4
34+
; RV64I-NEXT: srli a0, a0, 31
35+
; RV64I-NEXT: li a1, 1
36+
; RV64I-NEXT: slli a1, a1, 31
37+
; RV64I-NEXT: xor a2, a0, a1
3638
; RV64I-NEXT: .LBB0_2:
37-
; RV64I-NEXT: ret
38-
; RV64I-NEXT: .LBB0_3:
39-
; RV64I-NEXT: mv a0, a2
40-
; RV64I-NEXT: blt a1, a2, .LBB0_2
41-
; RV64I-NEXT: .LBB0_4:
42-
; RV64I-NEXT: lui a0, 524288
39+
; RV64I-NEXT: sext.w a0, a2
4340
; RV64I-NEXT: ret
4441
;
4542
; RV64IZbb-LABEL: func:

llvm/test/CodeGen/RISCV/sadd_sat_plus.ll

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,15 @@ define i32 @func32(i32 %x, i32 %y, i32 %z) nounwind {
3030
; RV64I: # %bb.0:
3131
; RV64I-NEXT: sext.w a0, a0
3232
; RV64I-NEXT: mulw a1, a1, a2
33+
; RV64I-NEXT: addw a2, a0, a1
3334
; RV64I-NEXT: add a0, a0, a1
34-
; RV64I-NEXT: lui a1, 524288
35-
; RV64I-NEXT: addiw a2, a1, -1
36-
; RV64I-NEXT: bge a0, a2, .LBB0_3
35+
; RV64I-NEXT: beq a2, a0, .LBB0_2
3736
; RV64I-NEXT: # %bb.1:
38-
; RV64I-NEXT: bge a1, a0, .LBB0_4
37+
; RV64I-NEXT: sraiw a0, a0, 31
38+
; RV64I-NEXT: lui a1, 524288
39+
; RV64I-NEXT: xor a0, a0, a1
3940
; RV64I-NEXT: .LBB0_2:
4041
; RV64I-NEXT: ret
41-
; RV64I-NEXT: .LBB0_3:
42-
; RV64I-NEXT: mv a0, a2
43-
; RV64I-NEXT: blt a1, a2, .LBB0_2
44-
; RV64I-NEXT: .LBB0_4:
45-
; RV64I-NEXT: lui a0, 524288
46-
; RV64I-NEXT: ret
4742
;
4843
; RV64IZbb-LABEL: func32:
4944
; RV64IZbb: # %bb.0:

llvm/test/CodeGen/RISCV/ssub_sat.ll

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,16 @@ define signext i32 @func(i32 signext %x, i32 signext %y) nounwind {
2727
;
2828
; RV64I-LABEL: func:
2929
; RV64I: # %bb.0:
30-
; RV64I-NEXT: sub a0, a0, a1
31-
; RV64I-NEXT: lui a1, 524288
32-
; RV64I-NEXT: addiw a2, a1, -1
33-
; RV64I-NEXT: bge a0, a2, .LBB0_3
30+
; RV64I-NEXT: sub a2, a0, a1
31+
; RV64I-NEXT: subw a0, a0, a1
32+
; RV64I-NEXT: beq a0, a2, .LBB0_2
3433
; RV64I-NEXT: # %bb.1:
35-
; RV64I-NEXT: bge a1, a0, .LBB0_4
34+
; RV64I-NEXT: srli a0, a0, 31
35+
; RV64I-NEXT: li a1, 1
36+
; RV64I-NEXT: slli a1, a1, 31
37+
; RV64I-NEXT: xor a2, a0, a1
3638
; RV64I-NEXT: .LBB0_2:
37-
; RV64I-NEXT: ret
38-
; RV64I-NEXT: .LBB0_3:
39-
; RV64I-NEXT: mv a0, a2
40-
; RV64I-NEXT: blt a1, a2, .LBB0_2
41-
; RV64I-NEXT: .LBB0_4:
42-
; RV64I-NEXT: lui a0, 524288
39+
; RV64I-NEXT: sext.w a0, a2
4340
; RV64I-NEXT: ret
4441
;
4542
; RV64IZbb-LABEL: func:

llvm/test/CodeGen/RISCV/ssub_sat_plus.ll

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,15 @@ define i32 @func32(i32 %x, i32 %y, i32 %z) nounwind {
3030
; RV64I: # %bb.0:
3131
; RV64I-NEXT: sext.w a0, a0
3232
; RV64I-NEXT: mulw a1, a1, a2
33+
; RV64I-NEXT: subw a2, a0, a1
3334
; RV64I-NEXT: sub a0, a0, a1
34-
; RV64I-NEXT: lui a1, 524288
35-
; RV64I-NEXT: addiw a2, a1, -1
36-
; RV64I-NEXT: bge a0, a2, .LBB0_3
35+
; RV64I-NEXT: beq a2, a0, .LBB0_2
3736
; RV64I-NEXT: # %bb.1:
38-
; RV64I-NEXT: bge a1, a0, .LBB0_4
37+
; RV64I-NEXT: sraiw a0, a0, 31
38+
; RV64I-NEXT: lui a1, 524288
39+
; RV64I-NEXT: xor a0, a0, a1
3940
; RV64I-NEXT: .LBB0_2:
4041
; RV64I-NEXT: ret
41-
; RV64I-NEXT: .LBB0_3:
42-
; RV64I-NEXT: mv a0, a2
43-
; RV64I-NEXT: blt a1, a2, .LBB0_2
44-
; RV64I-NEXT: .LBB0_4:
45-
; RV64I-NEXT: lui a0, 524288
46-
; RV64I-NEXT: ret
4742
;
4843
; RV64IZbb-LABEL: func32:
4944
; RV64IZbb: # %bb.0:

0 commit comments

Comments
 (0)