Skip to content

Commit 4cf2cf1

Browse files
authored
[RISCV][GISel] Stop over promoting G_SITOFP/UITOFP libcalls on RV64. (#118597)
When we have legal instructions we want to promote to sXLen and let isel pattern matching removing the and/sext_inreg. When using a libcall we want to use a 'si' libcall for small types instead of 'di'. To match the RV64 ABI, we need to sign extend `unsigned int` arguments. We reuse the shouldSignExtendTypeInLibCall hook from SelectionDAG.
1 parent 0d1e762 commit 4cf2cf1

File tree

5 files changed

+62
-43
lines changed

5 files changed

+62
-43
lines changed

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -882,11 +882,20 @@ static RTLIB::Libcall getConvRTLibDesc(unsigned Opcode, Type *ToType,
882882

883883
static LegalizerHelper::LegalizeResult
884884
conversionLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, Type *ToType,
885-
Type *FromType, LostDebugLocObserver &LocObserver) {
885+
Type *FromType, LostDebugLocObserver &LocObserver,
886+
const TargetLowering &TLI, bool IsSigned = false) {
887+
CallLowering::ArgInfo Arg = {MI.getOperand(1).getReg(), FromType, 0};
888+
if (FromType->isIntegerTy()) {
889+
if (TLI.shouldSignExtendTypeInLibCall(FromType, IsSigned))
890+
Arg.Flags[0].setSExt();
891+
else
892+
Arg.Flags[0].setZExt();
893+
}
894+
886895
RTLIB::Libcall Libcall = getConvRTLibDesc(MI.getOpcode(), ToType, FromType);
887-
return createLibcall(
888-
MIRBuilder, Libcall, {MI.getOperand(0).getReg(), ToType, 0},
889-
{{MI.getOperand(1).getReg(), FromType, 0}}, LocObserver, &MI);
896+
return createLibcall(MIRBuilder, Libcall,
897+
{MI.getOperand(0).getReg(), ToType, 0}, Arg, LocObserver,
898+
&MI);
890899
}
891900

892901
static RTLIB::Libcall
@@ -1308,7 +1317,7 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) {
13081317
if (!FromTy || !ToTy)
13091318
return UnableToLegalize;
13101319
LegalizeResult Status =
1311-
conversionLibcall(MI, MIRBuilder, ToTy, FromTy, LocObserver);
1320+
conversionLibcall(MI, MIRBuilder, ToTy, FromTy, LocObserver, TLI);
13121321
if (Status != Legalized)
13131322
return Status;
13141323
break;
@@ -1329,7 +1338,7 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) {
13291338
if ((ToSize != 32 && ToSize != 64 && ToSize != 128) || !FromTy)
13301339
return UnableToLegalize;
13311340
LegalizeResult Status = conversionLibcall(
1332-
MI, MIRBuilder, Type::getIntNTy(Ctx, ToSize), FromTy, LocObserver);
1341+
MI, MIRBuilder, Type::getIntNTy(Ctx, ToSize), FromTy, LocObserver, TLI);
13331342
if (Status != Legalized)
13341343
return Status;
13351344
break;
@@ -1341,8 +1350,10 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) {
13411350
getFloatTypeForLLT(Ctx, MRI.getType(MI.getOperand(0).getReg()));
13421351
if ((FromSize != 32 && FromSize != 64 && FromSize != 128) || !ToTy)
13431352
return UnableToLegalize;
1344-
LegalizeResult Status = conversionLibcall(
1345-
MI, MIRBuilder, ToTy, Type::getIntNTy(Ctx, FromSize), LocObserver);
1353+
bool IsSigned = MI.getOpcode() == TargetOpcode::G_SITOFP;
1354+
LegalizeResult Status =
1355+
conversionLibcall(MI, MIRBuilder, ToTy, Type::getIntNTy(Ctx, FromSize),
1356+
LocObserver, TLI, IsSigned);
13461357
if (Status != Legalized)
13471358
return Status;
13481359
break;

llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,19 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
565565
.legalFor(ST.hasStdExtD(), {{s64, sXLen}})
566566
.legalFor(ST.hasStdExtZfh(), {{s16, sXLen}})
567567
.widenScalarToNextPow2(1)
568-
.minScalar(1, sXLen)
568+
// Promote to XLen if the operation is legal.
569+
.widenScalarIf(
570+
[=, &ST](const LegalityQuery &Query) {
571+
return Query.Types[0].isScalar() && Query.Types[1].isScalar() &&
572+
(Query.Types[1].getSizeInBits() < ST.getXLen()) &&
573+
((ST.hasStdExtF() && Query.Types[1].getSizeInBits() == 32) ||
574+
(ST.hasStdExtD() && Query.Types[1].getSizeInBits() == 64) ||
575+
(ST.hasStdExtZfh() &&
576+
Query.Types[1].getSizeInBits() == 16));
577+
},
578+
LegalizeMutations::changeTo(1, sXLen))
579+
// Otherwise only promote to s32 since we have si libcalls.
580+
.minScalar(1, s32)
569581
.libcallFor({{s32, s32}, {s64, s32}, {s32, s64}, {s64, s64}})
570582
.libcallFor(ST.is64Bit(), {{s32, s128}, {s64, s128}});
571583

llvm/test/CodeGen/RISCV/GlobalISel/double-convert.ll

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ define double @fcvt_d_w(i32 %a) nounwind {
190190
; RV64I-NEXT: addi sp, sp, -16
191191
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
192192
; RV64I-NEXT: sext.w a0, a0
193-
; RV64I-NEXT: call __floatdidf
193+
; RV64I-NEXT: call __floatsidf
194194
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
195195
; RV64I-NEXT: addi sp, sp, 16
196196
; RV64I-NEXT: ret
@@ -220,7 +220,7 @@ define double @fcvt_d_w_load(ptr %p) nounwind {
220220
; RV64I-NEXT: addi sp, sp, -16
221221
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
222222
; RV64I-NEXT: lw a0, 0(a0)
223-
; RV64I-NEXT: call __floatdidf
223+
; RV64I-NEXT: call __floatsidf
224224
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
225225
; RV64I-NEXT: addi sp, sp, 16
226226
; RV64I-NEXT: ret
@@ -248,9 +248,8 @@ define double @fcvt_d_wu(i32 %a) nounwind {
248248
; RV64I: # %bb.0:
249249
; RV64I-NEXT: addi sp, sp, -16
250250
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
251-
; RV64I-NEXT: slli a0, a0, 32
252-
; RV64I-NEXT: srli a0, a0, 32
253-
; RV64I-NEXT: call __floatundidf
251+
; RV64I-NEXT: sext.w a0, a0
252+
; RV64I-NEXT: call __floatunsidf
254253
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
255254
; RV64I-NEXT: addi sp, sp, 16
256255
; RV64I-NEXT: ret
@@ -285,8 +284,8 @@ define double @fcvt_d_wu_load(ptr %p) nounwind {
285284
; RV64I: # %bb.0:
286285
; RV64I-NEXT: addi sp, sp, -16
287286
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
288-
; RV64I-NEXT: lwu a0, 0(a0)
289-
; RV64I-NEXT: call __floatundidf
287+
; RV64I-NEXT: lw a0, 0(a0)
288+
; RV64I-NEXT: call __floatunsidf
290289
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
291290
; RV64I-NEXT: addi sp, sp, 16
292291
; RV64I-NEXT: ret
@@ -541,7 +540,7 @@ define double @fcvt_d_w_i8(i8 signext %a) nounwind {
541540
; RV64I: # %bb.0:
542541
; RV64I-NEXT: addi sp, sp, -16
543542
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
544-
; RV64I-NEXT: call __floatdidf
543+
; RV64I-NEXT: call __floatsidf
545544
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
546545
; RV64I-NEXT: addi sp, sp, 16
547546
; RV64I-NEXT: ret
@@ -568,7 +567,7 @@ define double @fcvt_d_wu_i8(i8 zeroext %a) nounwind {
568567
; RV64I: # %bb.0:
569568
; RV64I-NEXT: addi sp, sp, -16
570569
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
571-
; RV64I-NEXT: call __floatundidf
570+
; RV64I-NEXT: call __floatunsidf
572571
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
573572
; RV64I-NEXT: addi sp, sp, 16
574573
; RV64I-NEXT: ret
@@ -595,7 +594,7 @@ define double @fcvt_d_w_i16(i16 signext %a) nounwind {
595594
; RV64I: # %bb.0:
596595
; RV64I-NEXT: addi sp, sp, -16
597596
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
598-
; RV64I-NEXT: call __floatdidf
597+
; RV64I-NEXT: call __floatsidf
599598
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
600599
; RV64I-NEXT: addi sp, sp, 16
601600
; RV64I-NEXT: ret
@@ -622,7 +621,7 @@ define double @fcvt_d_wu_i16(i16 zeroext %a) nounwind {
622621
; RV64I: # %bb.0:
623622
; RV64I-NEXT: addi sp, sp, -16
624623
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
625-
; RV64I-NEXT: call __floatundidf
624+
; RV64I-NEXT: call __floatunsidf
626625
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
627626
; RV64I-NEXT: addi sp, sp, 16
628627
; RV64I-NEXT: ret
@@ -673,7 +672,7 @@ define signext i32 @fcvt_d_w_demanded_bits(i32 signext %0, ptr %1) nounwind {
673672
; RV64I-NEXT: mv s0, a1
674673
; RV64I-NEXT: addiw s1, a0, 1
675674
; RV64I-NEXT: mv a0, s1
676-
; RV64I-NEXT: call __floatdidf
675+
; RV64I-NEXT: call __floatsidf
677676
; RV64I-NEXT: sd a0, 0(s0)
678677
; RV64I-NEXT: mv a0, s1
679678
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
@@ -729,9 +728,8 @@ define signext i32 @fcvt_d_wu_demanded_bits(i32 signext %0, ptr %1) nounwind {
729728
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
730729
; RV64I-NEXT: mv s0, a1
731730
; RV64I-NEXT: addiw s1, a0, 1
732-
; RV64I-NEXT: slli a0, s1, 32
733-
; RV64I-NEXT: srli a0, a0, 32
734-
; RV64I-NEXT: call __floatundidf
731+
; RV64I-NEXT: mv a0, s1
732+
; RV64I-NEXT: call __floatunsidf
735733
; RV64I-NEXT: sd a0, 0(s0)
736734
; RV64I-NEXT: mv a0, s1
737735
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload

llvm/test/CodeGen/RISCV/GlobalISel/float-convert.ll

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ define float @fcvt_s_w(i32 %a) nounwind {
176176
; RV64I-NEXT: addi sp, sp, -16
177177
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
178178
; RV64I-NEXT: sext.w a0, a0
179-
; RV64I-NEXT: call __floatdisf
179+
; RV64I-NEXT: call __floatsisf
180180
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
181181
; RV64I-NEXT: addi sp, sp, 16
182182
; RV64I-NEXT: ret
@@ -206,7 +206,7 @@ define float @fcvt_s_w_load(ptr %p) nounwind {
206206
; RV64I-NEXT: addi sp, sp, -16
207207
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
208208
; RV64I-NEXT: lw a0, 0(a0)
209-
; RV64I-NEXT: call __floatdisf
209+
; RV64I-NEXT: call __floatsisf
210210
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
211211
; RV64I-NEXT: addi sp, sp, 16
212212
; RV64I-NEXT: ret
@@ -234,9 +234,8 @@ define float @fcvt_s_wu(i32 %a) nounwind {
234234
; RV64I: # %bb.0:
235235
; RV64I-NEXT: addi sp, sp, -16
236236
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
237-
; RV64I-NEXT: slli a0, a0, 32
238-
; RV64I-NEXT: srli a0, a0, 32
239-
; RV64I-NEXT: call __floatundisf
237+
; RV64I-NEXT: sext.w a0, a0
238+
; RV64I-NEXT: call __floatunsisf
240239
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
241240
; RV64I-NEXT: addi sp, sp, 16
242241
; RV64I-NEXT: ret
@@ -271,8 +270,8 @@ define float @fcvt_s_wu_load(ptr %p) nounwind {
271270
; RV64I: # %bb.0:
272271
; RV64I-NEXT: addi sp, sp, -16
273272
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
274-
; RV64I-NEXT: lwu a0, 0(a0)
275-
; RV64I-NEXT: call __floatundisf
273+
; RV64I-NEXT: lw a0, 0(a0)
274+
; RV64I-NEXT: call __floatunsisf
276275
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
277276
; RV64I-NEXT: addi sp, sp, 16
278277
; RV64I-NEXT: ret
@@ -476,7 +475,7 @@ define float @fcvt_s_w_i8(i8 signext %a) nounwind {
476475
; RV64I: # %bb.0:
477476
; RV64I-NEXT: addi sp, sp, -16
478477
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
479-
; RV64I-NEXT: call __floatdisf
478+
; RV64I-NEXT: call __floatsisf
480479
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
481480
; RV64I-NEXT: addi sp, sp, 16
482481
; RV64I-NEXT: ret
@@ -503,7 +502,7 @@ define float @fcvt_s_wu_i8(i8 zeroext %a) nounwind {
503502
; RV64I: # %bb.0:
504503
; RV64I-NEXT: addi sp, sp, -16
505504
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
506-
; RV64I-NEXT: call __floatundisf
505+
; RV64I-NEXT: call __floatunsisf
507506
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
508507
; RV64I-NEXT: addi sp, sp, 16
509508
; RV64I-NEXT: ret
@@ -530,7 +529,7 @@ define float @fcvt_s_w_i16(i16 signext %a) nounwind {
530529
; RV64I: # %bb.0:
531530
; RV64I-NEXT: addi sp, sp, -16
532531
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
533-
; RV64I-NEXT: call __floatdisf
532+
; RV64I-NEXT: call __floatsisf
534533
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
535534
; RV64I-NEXT: addi sp, sp, 16
536535
; RV64I-NEXT: ret
@@ -557,7 +556,7 @@ define float @fcvt_s_wu_i16(i16 zeroext %a) nounwind {
557556
; RV64I: # %bb.0:
558557
; RV64I-NEXT: addi sp, sp, -16
559558
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
560-
; RV64I-NEXT: call __floatundisf
559+
; RV64I-NEXT: call __floatunsisf
561560
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
562561
; RV64I-NEXT: addi sp, sp, 16
563562
; RV64I-NEXT: ret
@@ -608,7 +607,7 @@ define signext i32 @fcvt_s_w_demanded_bits(i32 signext %0, ptr %1) nounwind {
608607
; RV64I-NEXT: mv s0, a1
609608
; RV64I-NEXT: addiw s1, a0, 1
610609
; RV64I-NEXT: mv a0, s1
611-
; RV64I-NEXT: call __floatdisf
610+
; RV64I-NEXT: call __floatsisf
612611
; RV64I-NEXT: sw a0, 0(s0)
613612
; RV64I-NEXT: mv a0, s1
614613
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
@@ -664,9 +663,8 @@ define signext i32 @fcvt_s_wu_demanded_bits(i32 signext %0, ptr %1) nounwind {
664663
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
665664
; RV64I-NEXT: mv s0, a1
666665
; RV64I-NEXT: addiw s1, a0, 1
667-
; RV64I-NEXT: slli a0, s1, 32
668-
; RV64I-NEXT: srli a0, a0, 32
669-
; RV64I-NEXT: call __floatundisf
666+
; RV64I-NEXT: mv a0, s1
667+
; RV64I-NEXT: call __floatunsisf
670668
; RV64I-NEXT: sw a0, 0(s0)
671669
; RV64I-NEXT: mv a0, s1
672670
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload

llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -539,12 +539,12 @@
539539
# DEBUG-NEXT: .. the first uncovered type index: 2, OK
540540
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
541541
# DEBUG-NEXT: G_SITOFP (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
542-
# DEBUG-NEXT: .. the first uncovered type index: 2, OK
543-
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
542+
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
543+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
544544
# DEBUG-NEXT: G_UITOFP (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
545545
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
546-
# DEBUG-NEXT: .. the first uncovered type index: 2, OK
547-
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
546+
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
547+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
548548
# DEBUG-NEXT: G_FPTOSI_SAT (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
549549
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
550550
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined

0 commit comments

Comments
 (0)