Skip to content

Commit a15400d

Browse files
authored
[RISCV][GISel] Support f32/f64 ldexp. (#117941)
The existing libcall lowering in LegalizerHelper.cpp did not account for one operand being integer. Reuse the G_FPOWI code to fix this.
1 parent bde79c0 commit a15400d

File tree

5 files changed

+92
-5
lines changed

5 files changed

+92
-5
lines changed

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,7 +1233,6 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) {
12331233
case TargetOpcode::G_FLOG10:
12341234
case TargetOpcode::G_FLOG:
12351235
case TargetOpcode::G_FLOG2:
1236-
case TargetOpcode::G_FLDEXP:
12371236
case TargetOpcode::G_FEXP:
12381237
case TargetOpcode::G_FEXP2:
12391238
case TargetOpcode::G_FEXP10:
@@ -1279,7 +1278,8 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) {
12791278
MI.eraseFromParent();
12801279
return Legalized;
12811280
}
1282-
case TargetOpcode::G_FPOWI: {
1281+
case TargetOpcode::G_FPOWI:
1282+
case TargetOpcode::G_FLDEXP: {
12831283
LLT LLTy = MRI.getType(MI.getOperand(0).getReg());
12841284
unsigned Size = LLTy.getSizeInBits();
12851285
Type *HLTy = getFloatTypeForLLT(Ctx, LLTy);

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,8 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
579579
G_FASIN, G_FATAN, G_FATAN2, G_FCOSH, G_FSINH,
580580
G_FTANH})
581581
.libcallFor({s32, s64});
582-
getActionDefinitionsBuilder(G_FPOWI).libcallFor({{s32, s32}, {s64, s32}});
582+
getActionDefinitionsBuilder({G_FPOWI, G_FLDEXP})
583+
.libcallFor({{s32, s32}, {s64, s32}});
583584

584585
getActionDefinitionsBuilder(G_VASTART).customFor({p0});
585586

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

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,49 @@ define double @tan_f64(double %a) nounwind {
11031103
%1 = call double @llvm.tan.f64(double %a)
11041104
ret double %1
11051105
}
1106+
1107+
define double @ldexp_double(double %x, i32 %y) nounwind {
1108+
; RV32IFD-LABEL: ldexp_double:
1109+
; RV32IFD: # %bb.0:
1110+
; RV32IFD-NEXT: addi sp, sp, -16
1111+
; RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
1112+
; RV32IFD-NEXT: call ldexp
1113+
; RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
1114+
; RV32IFD-NEXT: addi sp, sp, 16
1115+
; RV32IFD-NEXT: ret
1116+
;
1117+
; RV64IFD-LABEL: ldexp_double:
1118+
; RV64IFD: # %bb.0:
1119+
; RV64IFD-NEXT: addi sp, sp, -16
1120+
; RV64IFD-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
1121+
; RV64IFD-NEXT: sext.w a0, a0
1122+
; RV64IFD-NEXT: call ldexp
1123+
; RV64IFD-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
1124+
; RV64IFD-NEXT: addi sp, sp, 16
1125+
; RV64IFD-NEXT: ret
1126+
;
1127+
; RV32I-LABEL: ldexp_double:
1128+
; RV32I: # %bb.0:
1129+
; RV32I-NEXT: addi sp, sp, -16
1130+
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
1131+
; RV32I-NEXT: call ldexp
1132+
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
1133+
; RV32I-NEXT: addi sp, sp, 16
1134+
; RV32I-NEXT: ret
1135+
;
1136+
; RV64I-LABEL: ldexp_double:
1137+
; RV64I: # %bb.0:
1138+
; RV64I-NEXT: addi sp, sp, -16
1139+
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
1140+
; RV64I-NEXT: sext.w a1, a1
1141+
; RV64I-NEXT: call ldexp
1142+
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
1143+
; RV64I-NEXT: addi sp, sp, 16
1144+
; RV64I-NEXT: ret
1145+
%z = call double @llvm.ldexp.f64.i32(double %x, i32 %y)
1146+
ret double %z
1147+
}
1148+
11061149
define double @asin_f64(double %a) nounwind {
11071150
; RV32IFD-LABEL: asin_f64:
11081151
; RV32IFD: # %bb.0:

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,6 +1450,48 @@ define float @tan_f32(float %a) nounwind {
14501450
ret float %1
14511451
}
14521452

1453+
define float @ldexp_float(float %x, i32 %y) nounwind {
1454+
; RV32IF-LABEL: ldexp_float:
1455+
; RV32IF: # %bb.0:
1456+
; RV32IF-NEXT: addi sp, sp, -16
1457+
; RV32IF-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
1458+
; RV32IF-NEXT: call ldexpf
1459+
; RV32IF-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
1460+
; RV32IF-NEXT: addi sp, sp, 16
1461+
; RV32IF-NEXT: ret
1462+
;
1463+
; RV64IF-LABEL: ldexp_float:
1464+
; RV64IF: # %bb.0:
1465+
; RV64IF-NEXT: addi sp, sp, -16
1466+
; RV64IF-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
1467+
; RV64IF-NEXT: sext.w a0, a0
1468+
; RV64IF-NEXT: call ldexpf
1469+
; RV64IF-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
1470+
; RV64IF-NEXT: addi sp, sp, 16
1471+
; RV64IF-NEXT: ret
1472+
;
1473+
; RV32I-LABEL: ldexp_float:
1474+
; RV32I: # %bb.0:
1475+
; RV32I-NEXT: addi sp, sp, -16
1476+
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
1477+
; RV32I-NEXT: call ldexpf
1478+
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
1479+
; RV32I-NEXT: addi sp, sp, 16
1480+
; RV32I-NEXT: ret
1481+
;
1482+
; RV64I-LABEL: ldexp_float:
1483+
; RV64I: # %bb.0:
1484+
; RV64I-NEXT: addi sp, sp, -16
1485+
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
1486+
; RV64I-NEXT: sext.w a1, a1
1487+
; RV64I-NEXT: call ldexpf
1488+
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
1489+
; RV64I-NEXT: addi sp, sp, 16
1490+
; RV64I-NEXT: ret
1491+
%z = call float @llvm.ldexp.f32.i32(float %x, i32 %y)
1492+
ret float %z
1493+
}
1494+
14531495
define float @asin_f32(float %a) nounwind {
14541496
; RV32IF-LABEL: asin_f32:
14551497
; RV32IF: # %bb.0:

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -508,8 +508,9 @@
508508
# DEBUG-NEXT: .. the first uncovered type index: 1, OK
509509
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
510510
# DEBUG-NEXT: G_FLDEXP (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
511-
# DEBUG-NEXT:.. type index coverage check SKIPPED: no rules defined
512-
# DEBUG-NEXT:.. imm index coverage check SKIPPED: no rules defined
511+
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
512+
# DEBUG-NEXT: .. the first uncovered type index: 2, OK
513+
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
513514
# DEBUG-NEXT: G_FFREXP (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
514515
# DEBUG-NEXT:.. type index coverage check SKIPPED: no rules defined
515516
# DEBUG-NEXT:.. imm index coverage check SKIPPED: no rules defined

0 commit comments

Comments
 (0)