-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[RISCV][GISel] Stop over promoting G_SITOFP/UITOFP libcalls on RV64. #118597
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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.
@llvm/pr-subscribers-llvm-globalisel Author: Craig Topper (topperc) ChangesWhen 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 Full diff: https://github.com/llvm/llvm-project/pull/118597.diff 5 Files Affected:
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index d4323cd728437e..cf835ad187f818 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -882,11 +882,20 @@ static RTLIB::Libcall getConvRTLibDesc(unsigned Opcode, Type *ToType,
static LegalizerHelper::LegalizeResult
conversionLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, Type *ToType,
- Type *FromType, LostDebugLocObserver &LocObserver) {
+ Type *FromType, LostDebugLocObserver &LocObserver,
+ const TargetLowering &TLI, bool IsSigned = false) {
+ CallLowering::ArgInfo Arg = {MI.getOperand(1).getReg(), FromType, 0};
+ if (FromType->isIntegerTy()) {
+ if (TLI.shouldSignExtendTypeInLibCall(FromType, IsSigned))
+ Arg.Flags[0].setSExt();
+ else
+ Arg.Flags[0].setZExt();
+ }
+
RTLIB::Libcall Libcall = getConvRTLibDesc(MI.getOpcode(), ToType, FromType);
- return createLibcall(
- MIRBuilder, Libcall, {MI.getOperand(0).getReg(), ToType, 0},
- {{MI.getOperand(1).getReg(), FromType, 0}}, LocObserver, &MI);
+ return createLibcall(MIRBuilder, Libcall,
+ {MI.getOperand(0).getReg(), ToType, 0}, Arg, LocObserver,
+ &MI);
}
static RTLIB::Libcall
@@ -1308,7 +1317,7 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) {
if (!FromTy || !ToTy)
return UnableToLegalize;
LegalizeResult Status =
- conversionLibcall(MI, MIRBuilder, ToTy, FromTy, LocObserver);
+ conversionLibcall(MI, MIRBuilder, ToTy, FromTy, LocObserver, TLI);
if (Status != Legalized)
return Status;
break;
@@ -1329,7 +1338,7 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) {
if ((ToSize != 32 && ToSize != 64 && ToSize != 128) || !FromTy)
return UnableToLegalize;
LegalizeResult Status = conversionLibcall(
- MI, MIRBuilder, Type::getIntNTy(Ctx, ToSize), FromTy, LocObserver);
+ MI, MIRBuilder, Type::getIntNTy(Ctx, ToSize), FromTy, LocObserver, TLI);
if (Status != Legalized)
return Status;
break;
@@ -1341,8 +1350,10 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) {
getFloatTypeForLLT(Ctx, MRI.getType(MI.getOperand(0).getReg()));
if ((FromSize != 32 && FromSize != 64 && FromSize != 128) || !ToTy)
return UnableToLegalize;
- LegalizeResult Status = conversionLibcall(
- MI, MIRBuilder, ToTy, Type::getIntNTy(Ctx, FromSize), LocObserver);
+ bool IsSigned = MI.getOpcode() == TargetOpcode::G_SITOFP;
+ LegalizeResult Status =
+ conversionLibcall(MI, MIRBuilder, ToTy, Type::getIntNTy(Ctx, FromSize),
+ LocObserver, TLI, IsSigned);
if (Status != Legalized)
return Status;
break;
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index 911827da061974..193fbefe421bf6 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -565,7 +565,19 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
.legalFor(ST.hasStdExtD(), {{s64, sXLen}})
.legalFor(ST.hasStdExtZfh(), {{s16, sXLen}})
.widenScalarToNextPow2(1)
- .minScalar(1, sXLen)
+ // Promote to XLen if the operation is legal.
+ .widenScalarIf(
+ [=, &ST](const LegalityQuery &Query) {
+ return Query.Types[0].isScalar() && Query.Types[1].isScalar() &&
+ (Query.Types[1].getSizeInBits() < ST.getXLen()) &&
+ ((ST.hasStdExtF() && Query.Types[1].getSizeInBits() == 32) ||
+ (ST.hasStdExtD() && Query.Types[1].getSizeInBits() == 64) ||
+ (ST.hasStdExtZfh() &&
+ Query.Types[1].getSizeInBits() == 16));
+ },
+ LegalizeMutations::changeTo(1, sXLen))
+ // Otherwise only promote to s32 since we have si libcalls.
+ .minScalar(1, s32)
.libcallFor({{s32, s32}, {s64, s32}, {s32, s64}, {s64, s64}})
.libcallFor(ST.is64Bit(), {{s32, s128}, {s64, s128}});
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/double-convert.ll b/llvm/test/CodeGen/RISCV/GlobalISel/double-convert.ll
index b0711d7fbc772c..6b623fd6867a2d 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/double-convert.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/double-convert.ll
@@ -190,7 +190,7 @@ define double @fcvt_d_w(i32 %a) nounwind {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: sext.w a0, a0
-; RV64I-NEXT: call __floatdidf
+; RV64I-NEXT: call __floatsidf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -220,7 +220,7 @@ define double @fcvt_d_w_load(ptr %p) nounwind {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: lw a0, 0(a0)
-; RV64I-NEXT: call __floatdidf
+; RV64I-NEXT: call __floatsidf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -248,9 +248,8 @@ define double @fcvt_d_wu(i32 %a) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: slli a0, a0, 32
-; RV64I-NEXT: srli a0, a0, 32
-; RV64I-NEXT: call __floatundidf
+; RV64I-NEXT: sext.w a0, a0
+; RV64I-NEXT: call __floatunsidf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -285,8 +284,8 @@ define double @fcvt_d_wu_load(ptr %p) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: lwu a0, 0(a0)
-; RV64I-NEXT: call __floatundidf
+; RV64I-NEXT: lw a0, 0(a0)
+; RV64I-NEXT: call __floatunsidf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -541,7 +540,7 @@ define double @fcvt_d_w_i8(i8 signext %a) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: call __floatdidf
+; RV64I-NEXT: call __floatsidf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -568,7 +567,7 @@ define double @fcvt_d_wu_i8(i8 zeroext %a) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: call __floatundidf
+; RV64I-NEXT: call __floatunsidf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -595,7 +594,7 @@ define double @fcvt_d_w_i16(i16 signext %a) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: call __floatdidf
+; RV64I-NEXT: call __floatsidf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -622,7 +621,7 @@ define double @fcvt_d_wu_i16(i16 zeroext %a) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: call __floatundidf
+; RV64I-NEXT: call __floatunsidf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -673,7 +672,7 @@ define signext i32 @fcvt_d_w_demanded_bits(i32 signext %0, ptr %1) nounwind {
; RV64I-NEXT: mv s0, a1
; RV64I-NEXT: addiw s1, a0, 1
; RV64I-NEXT: mv a0, s1
-; RV64I-NEXT: call __floatdidf
+; RV64I-NEXT: call __floatsidf
; RV64I-NEXT: sd a0, 0(s0)
; RV64I-NEXT: mv a0, s1
; 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 {
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: mv s0, a1
; RV64I-NEXT: addiw s1, a0, 1
-; RV64I-NEXT: slli a0, s1, 32
-; RV64I-NEXT: srli a0, a0, 32
-; RV64I-NEXT: call __floatundidf
+; RV64I-NEXT: mv a0, s1
+; RV64I-NEXT: call __floatunsidf
; RV64I-NEXT: sd a0, 0(s0)
; RV64I-NEXT: mv a0, s1
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/float-convert.ll b/llvm/test/CodeGen/RISCV/GlobalISel/float-convert.ll
index a14c06726ef5fb..c310ee8e316717 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/float-convert.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/float-convert.ll
@@ -176,7 +176,7 @@ define float @fcvt_s_w(i32 %a) nounwind {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: sext.w a0, a0
-; RV64I-NEXT: call __floatdisf
+; RV64I-NEXT: call __floatsisf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -206,7 +206,7 @@ define float @fcvt_s_w_load(ptr %p) nounwind {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: lw a0, 0(a0)
-; RV64I-NEXT: call __floatdisf
+; RV64I-NEXT: call __floatsisf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -234,9 +234,8 @@ define float @fcvt_s_wu(i32 %a) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: slli a0, a0, 32
-; RV64I-NEXT: srli a0, a0, 32
-; RV64I-NEXT: call __floatundisf
+; RV64I-NEXT: sext.w a0, a0
+; RV64I-NEXT: call __floatunsisf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -271,8 +270,8 @@ define float @fcvt_s_wu_load(ptr %p) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: lwu a0, 0(a0)
-; RV64I-NEXT: call __floatundisf
+; RV64I-NEXT: lw a0, 0(a0)
+; RV64I-NEXT: call __floatunsisf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -476,7 +475,7 @@ define float @fcvt_s_w_i8(i8 signext %a) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: call __floatdisf
+; RV64I-NEXT: call __floatsisf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -503,7 +502,7 @@ define float @fcvt_s_wu_i8(i8 zeroext %a) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: call __floatundisf
+; RV64I-NEXT: call __floatunsisf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -530,7 +529,7 @@ define float @fcvt_s_w_i16(i16 signext %a) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: call __floatdisf
+; RV64I-NEXT: call __floatsisf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -557,7 +556,7 @@ define float @fcvt_s_wu_i16(i16 zeroext %a) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: call __floatundisf
+; RV64I-NEXT: call __floatunsisf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -608,7 +607,7 @@ define signext i32 @fcvt_s_w_demanded_bits(i32 signext %0, ptr %1) nounwind {
; RV64I-NEXT: mv s0, a1
; RV64I-NEXT: addiw s1, a0, 1
; RV64I-NEXT: mv a0, s1
-; RV64I-NEXT: call __floatdisf
+; RV64I-NEXT: call __floatsisf
; RV64I-NEXT: sw a0, 0(s0)
; RV64I-NEXT: mv a0, s1
; 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 {
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: mv s0, a1
; RV64I-NEXT: addiw s1, a0, 1
-; RV64I-NEXT: slli a0, s1, 32
-; RV64I-NEXT: srli a0, a0, 32
-; RV64I-NEXT: call __floatundisf
+; RV64I-NEXT: mv a0, s1
+; RV64I-NEXT: call __floatunsisf
; RV64I-NEXT: sw a0, 0(s0)
; RV64I-NEXT: mv a0, s1
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
index 0d9d539a1a80ed..0191923e01f98d 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
@@ -531,12 +531,12 @@
# DEBUG-NEXT: .. the first uncovered type index: 2, OK
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
# DEBUG-NEXT: G_SITOFP (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
-# DEBUG-NEXT: .. the first uncovered type index: 2, OK
-# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
+# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
+# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: G_UITOFP (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
-# DEBUG-NEXT: .. the first uncovered type index: 2, OK
-# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
+# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
+# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: G_FPTOSI_SAT (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
|
@llvm/pr-subscribers-backend-risc-v Author: Craig Topper (topperc) ChangesWhen 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 Full diff: https://github.com/llvm/llvm-project/pull/118597.diff 5 Files Affected:
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index d4323cd728437e..cf835ad187f818 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -882,11 +882,20 @@ static RTLIB::Libcall getConvRTLibDesc(unsigned Opcode, Type *ToType,
static LegalizerHelper::LegalizeResult
conversionLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, Type *ToType,
- Type *FromType, LostDebugLocObserver &LocObserver) {
+ Type *FromType, LostDebugLocObserver &LocObserver,
+ const TargetLowering &TLI, bool IsSigned = false) {
+ CallLowering::ArgInfo Arg = {MI.getOperand(1).getReg(), FromType, 0};
+ if (FromType->isIntegerTy()) {
+ if (TLI.shouldSignExtendTypeInLibCall(FromType, IsSigned))
+ Arg.Flags[0].setSExt();
+ else
+ Arg.Flags[0].setZExt();
+ }
+
RTLIB::Libcall Libcall = getConvRTLibDesc(MI.getOpcode(), ToType, FromType);
- return createLibcall(
- MIRBuilder, Libcall, {MI.getOperand(0).getReg(), ToType, 0},
- {{MI.getOperand(1).getReg(), FromType, 0}}, LocObserver, &MI);
+ return createLibcall(MIRBuilder, Libcall,
+ {MI.getOperand(0).getReg(), ToType, 0}, Arg, LocObserver,
+ &MI);
}
static RTLIB::Libcall
@@ -1308,7 +1317,7 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) {
if (!FromTy || !ToTy)
return UnableToLegalize;
LegalizeResult Status =
- conversionLibcall(MI, MIRBuilder, ToTy, FromTy, LocObserver);
+ conversionLibcall(MI, MIRBuilder, ToTy, FromTy, LocObserver, TLI);
if (Status != Legalized)
return Status;
break;
@@ -1329,7 +1338,7 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) {
if ((ToSize != 32 && ToSize != 64 && ToSize != 128) || !FromTy)
return UnableToLegalize;
LegalizeResult Status = conversionLibcall(
- MI, MIRBuilder, Type::getIntNTy(Ctx, ToSize), FromTy, LocObserver);
+ MI, MIRBuilder, Type::getIntNTy(Ctx, ToSize), FromTy, LocObserver, TLI);
if (Status != Legalized)
return Status;
break;
@@ -1341,8 +1350,10 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) {
getFloatTypeForLLT(Ctx, MRI.getType(MI.getOperand(0).getReg()));
if ((FromSize != 32 && FromSize != 64 && FromSize != 128) || !ToTy)
return UnableToLegalize;
- LegalizeResult Status = conversionLibcall(
- MI, MIRBuilder, ToTy, Type::getIntNTy(Ctx, FromSize), LocObserver);
+ bool IsSigned = MI.getOpcode() == TargetOpcode::G_SITOFP;
+ LegalizeResult Status =
+ conversionLibcall(MI, MIRBuilder, ToTy, Type::getIntNTy(Ctx, FromSize),
+ LocObserver, TLI, IsSigned);
if (Status != Legalized)
return Status;
break;
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index 911827da061974..193fbefe421bf6 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -565,7 +565,19 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
.legalFor(ST.hasStdExtD(), {{s64, sXLen}})
.legalFor(ST.hasStdExtZfh(), {{s16, sXLen}})
.widenScalarToNextPow2(1)
- .minScalar(1, sXLen)
+ // Promote to XLen if the operation is legal.
+ .widenScalarIf(
+ [=, &ST](const LegalityQuery &Query) {
+ return Query.Types[0].isScalar() && Query.Types[1].isScalar() &&
+ (Query.Types[1].getSizeInBits() < ST.getXLen()) &&
+ ((ST.hasStdExtF() && Query.Types[1].getSizeInBits() == 32) ||
+ (ST.hasStdExtD() && Query.Types[1].getSizeInBits() == 64) ||
+ (ST.hasStdExtZfh() &&
+ Query.Types[1].getSizeInBits() == 16));
+ },
+ LegalizeMutations::changeTo(1, sXLen))
+ // Otherwise only promote to s32 since we have si libcalls.
+ .minScalar(1, s32)
.libcallFor({{s32, s32}, {s64, s32}, {s32, s64}, {s64, s64}})
.libcallFor(ST.is64Bit(), {{s32, s128}, {s64, s128}});
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/double-convert.ll b/llvm/test/CodeGen/RISCV/GlobalISel/double-convert.ll
index b0711d7fbc772c..6b623fd6867a2d 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/double-convert.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/double-convert.ll
@@ -190,7 +190,7 @@ define double @fcvt_d_w(i32 %a) nounwind {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: sext.w a0, a0
-; RV64I-NEXT: call __floatdidf
+; RV64I-NEXT: call __floatsidf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -220,7 +220,7 @@ define double @fcvt_d_w_load(ptr %p) nounwind {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: lw a0, 0(a0)
-; RV64I-NEXT: call __floatdidf
+; RV64I-NEXT: call __floatsidf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -248,9 +248,8 @@ define double @fcvt_d_wu(i32 %a) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: slli a0, a0, 32
-; RV64I-NEXT: srli a0, a0, 32
-; RV64I-NEXT: call __floatundidf
+; RV64I-NEXT: sext.w a0, a0
+; RV64I-NEXT: call __floatunsidf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -285,8 +284,8 @@ define double @fcvt_d_wu_load(ptr %p) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: lwu a0, 0(a0)
-; RV64I-NEXT: call __floatundidf
+; RV64I-NEXT: lw a0, 0(a0)
+; RV64I-NEXT: call __floatunsidf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -541,7 +540,7 @@ define double @fcvt_d_w_i8(i8 signext %a) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: call __floatdidf
+; RV64I-NEXT: call __floatsidf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -568,7 +567,7 @@ define double @fcvt_d_wu_i8(i8 zeroext %a) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: call __floatundidf
+; RV64I-NEXT: call __floatunsidf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -595,7 +594,7 @@ define double @fcvt_d_w_i16(i16 signext %a) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: call __floatdidf
+; RV64I-NEXT: call __floatsidf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -622,7 +621,7 @@ define double @fcvt_d_wu_i16(i16 zeroext %a) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: call __floatundidf
+; RV64I-NEXT: call __floatunsidf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -673,7 +672,7 @@ define signext i32 @fcvt_d_w_demanded_bits(i32 signext %0, ptr %1) nounwind {
; RV64I-NEXT: mv s0, a1
; RV64I-NEXT: addiw s1, a0, 1
; RV64I-NEXT: mv a0, s1
-; RV64I-NEXT: call __floatdidf
+; RV64I-NEXT: call __floatsidf
; RV64I-NEXT: sd a0, 0(s0)
; RV64I-NEXT: mv a0, s1
; 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 {
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: mv s0, a1
; RV64I-NEXT: addiw s1, a0, 1
-; RV64I-NEXT: slli a0, s1, 32
-; RV64I-NEXT: srli a0, a0, 32
-; RV64I-NEXT: call __floatundidf
+; RV64I-NEXT: mv a0, s1
+; RV64I-NEXT: call __floatunsidf
; RV64I-NEXT: sd a0, 0(s0)
; RV64I-NEXT: mv a0, s1
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/float-convert.ll b/llvm/test/CodeGen/RISCV/GlobalISel/float-convert.ll
index a14c06726ef5fb..c310ee8e316717 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/float-convert.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/float-convert.ll
@@ -176,7 +176,7 @@ define float @fcvt_s_w(i32 %a) nounwind {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: sext.w a0, a0
-; RV64I-NEXT: call __floatdisf
+; RV64I-NEXT: call __floatsisf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -206,7 +206,7 @@ define float @fcvt_s_w_load(ptr %p) nounwind {
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: lw a0, 0(a0)
-; RV64I-NEXT: call __floatdisf
+; RV64I-NEXT: call __floatsisf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -234,9 +234,8 @@ define float @fcvt_s_wu(i32 %a) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: slli a0, a0, 32
-; RV64I-NEXT: srli a0, a0, 32
-; RV64I-NEXT: call __floatundisf
+; RV64I-NEXT: sext.w a0, a0
+; RV64I-NEXT: call __floatunsisf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -271,8 +270,8 @@ define float @fcvt_s_wu_load(ptr %p) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: lwu a0, 0(a0)
-; RV64I-NEXT: call __floatundisf
+; RV64I-NEXT: lw a0, 0(a0)
+; RV64I-NEXT: call __floatunsisf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -476,7 +475,7 @@ define float @fcvt_s_w_i8(i8 signext %a) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: call __floatdisf
+; RV64I-NEXT: call __floatsisf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -503,7 +502,7 @@ define float @fcvt_s_wu_i8(i8 zeroext %a) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: call __floatundisf
+; RV64I-NEXT: call __floatunsisf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -530,7 +529,7 @@ define float @fcvt_s_w_i16(i16 signext %a) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: call __floatdisf
+; RV64I-NEXT: call __floatsisf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -557,7 +556,7 @@ define float @fcvt_s_wu_i16(i16 zeroext %a) nounwind {
; RV64I: # %bb.0:
; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: call __floatundisf
+; RV64I-NEXT: call __floatunsisf
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 16
; RV64I-NEXT: ret
@@ -608,7 +607,7 @@ define signext i32 @fcvt_s_w_demanded_bits(i32 signext %0, ptr %1) nounwind {
; RV64I-NEXT: mv s0, a1
; RV64I-NEXT: addiw s1, a0, 1
; RV64I-NEXT: mv a0, s1
-; RV64I-NEXT: call __floatdisf
+; RV64I-NEXT: call __floatsisf
; RV64I-NEXT: sw a0, 0(s0)
; RV64I-NEXT: mv a0, s1
; 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 {
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT: mv s0, a1
; RV64I-NEXT: addiw s1, a0, 1
-; RV64I-NEXT: slli a0, s1, 32
-; RV64I-NEXT: srli a0, a0, 32
-; RV64I-NEXT: call __floatundisf
+; RV64I-NEXT: mv a0, s1
+; RV64I-NEXT: call __floatunsisf
; RV64I-NEXT: sw a0, 0(s0)
; RV64I-NEXT: mv a0, s1
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
index 0d9d539a1a80ed..0191923e01f98d 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
@@ -531,12 +531,12 @@
# DEBUG-NEXT: .. the first uncovered type index: 2, OK
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
# DEBUG-NEXT: G_SITOFP (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
-# DEBUG-NEXT: .. the first uncovered type index: 2, OK
-# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
+# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
+# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: G_UITOFP (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
-# DEBUG-NEXT: .. the first uncovered type index: 2, OK
-# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
+# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
+# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: G_FPTOSI_SAT (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
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.