[PATCH] D102918: [RISCV] Avoid undef result due to promotion of FPOWI exponent

Bjorn Pettersson via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri May 21 06:30:49 PDT 2021


bjope created this revision.
bjope added reviewers: efriedma, frasercrmck.
Herald added subscribers: vkmr, evandro, luismarques, apazos, sameer.abuasal, s.egerton, Jim, benna, psnobl, jocewei, PkmX, the_o, brucehoult, MartinMosbeck, rogfer01, edward-jones, zzheng, jrtc27, shiva0217, kito-cheng, niosHD, sabuasal, simoncook, johnrusso, rbar, asb, hiraditya.
bjope requested review of this revision.
Herald added a subscriber: MaskRay.
Herald added a project: LLVM.

The 64-bit RISCV target has no legal i32 type. So when SelectionDAG
is legalizing the types for FPOWI the exponent is promoted to i64.
However, the FPOWI/STRICT_FPOWI are defined as having undefined
result if the exponent is larger than i32 (it should probably say
"if the exponent is larger than sizeof(int) for the target" as it
shold be possible to lower those nodes to RTLIB::POWI libcalls and
those runtime library functions is using "int" as input arguments).

This patch can be seen as a workaround to avoid that we promote
the exponent to i64 (making the result undefined). As a simple
solution we expand FPOWI/STRICT_FPOWI into SINT_TO_FP+FPOW. This
is the same rewrite as normally done by LegalizeDAG when the
RTLIB::POWI libcalls aren't allowed.

I leave it as a future FIXME to implement legalization/lowering
of FPOWI/STRICT_FPOWI into using RTLIB::POWI libcalls again. Someone
that knows about RISCV and calling conventions can perhaps figure
out how to do that properly.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D102918

Files:
  llvm/lib/Target/RISCV/RISCVISelLowering.cpp
  llvm/test/CodeGen/RISCV/double-intrinsics.ll
  llvm/test/CodeGen/RISCV/float-intrinsics.ll
  llvm/test/CodeGen/RISCV/rv64i-single-softfloat.ll


Index: llvm/test/CodeGen/RISCV/rv64i-single-softfloat.ll
===================================================================
--- llvm/test/CodeGen/RISCV/rv64i-single-softfloat.ll
+++ llvm/test/CodeGen/RISCV/rv64i-single-softfloat.ll
@@ -670,8 +670,14 @@
 ; RV64I:       # %bb.0:
 ; RV64I-NEXT:    addi sp, sp, -16
 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT:    sext.w a1, a1
-; RV64I-NEXT:    call __powisf2 at plt
+; RV64I-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
+; RV64I-NEXT:    mv s0, a0
+; RV64I-NEXT:    sext.w a0, a1
+; RV64I-NEXT:    call __floatsisf at plt
+; RV64I-NEXT:    mv a1, a0
+; RV64I-NEXT:    mv a0, s0
+; RV64I-NEXT:    call powf at plt
+; RV64I-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
 ; RV64I-NEXT:    addi sp, sp, 16
 ; RV64I-NEXT:    ret
Index: llvm/test/CodeGen/RISCV/float-intrinsics.ll
===================================================================
--- llvm/test/CodeGen/RISCV/float-intrinsics.ll
+++ llvm/test/CodeGen/RISCV/float-intrinsics.ll
@@ -44,8 +44,9 @@
 ; RV64IF:       # %bb.0:
 ; RV64IF-NEXT:    addi sp, sp, -16
 ; RV64IF-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
-; RV64IF-NEXT:    sext.w a1, a1
-; RV64IF-NEXT:    call __powisf2 at plt
+; RV64IF-NEXT:    fcvt.s.w ft0, a1
+; RV64IF-NEXT:    fmv.x.w a1, ft0
+; RV64IF-NEXT:    call powf at plt
 ; RV64IF-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
 ; RV64IF-NEXT:    addi sp, sp, 16
 ; RV64IF-NEXT:    ret
Index: llvm/test/CodeGen/RISCV/double-intrinsics.ll
===================================================================
--- llvm/test/CodeGen/RISCV/double-intrinsics.ll
+++ llvm/test/CodeGen/RISCV/double-intrinsics.ll
@@ -46,8 +46,9 @@
 ; RV64IFD:       # %bb.0:
 ; RV64IFD-NEXT:    addi sp, sp, -16
 ; RV64IFD-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
-; RV64IFD-NEXT:    sext.w a1, a1
-; RV64IFD-NEXT:    call __powidf2 at plt
+; RV64IFD-NEXT:    fcvt.d.w ft0, a1
+; RV64IFD-NEXT:    fmv.x.d a1, ft0
+; RV64IFD-NEXT:    call pow at plt
 ; RV64IFD-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
 ; RV64IFD-NEXT:    addi sp, sp, 16
 ; RV64IFD-NEXT:    ret
Index: llvm/lib/Target/RISCV/RISCVISelLowering.cpp
===================================================================
--- llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -818,6 +818,10 @@
     setTargetDAGCombine(ISD::MGATHER);
     setTargetDAGCombine(ISD::MSCATTER);
   }
+  if (Subtarget.is64Bit()) {
+    setTargetDAGCombine(ISD::FPOWI);
+    setTargetDAGCombine(ISD::STRICT_FPOWI);
+  }
 }
 
 EVT RISCVTargetLowering::getSetCCResultType(const DataLayout &DL,
@@ -5919,6 +5923,23 @@
          Index, MGSN->getScale()},
         MGSN->getMemOperand(), NewIndexTy, MSN->isTruncatingStore());
   }
+  case ISD::FPOWI:
+  case ISD::STRICT_FPOWI: {
+    if (!DCI.isBeforeLegalize())
+      break;
+    // FIXME: It should be possible to lower these to RTLIB::POWI libcalls. Now
+    // we instead rewrite into using FPOW in case the type of the exponent isn't
+    // legal (to avoid that TypeLegalization promotes the exponent in FPOWI to
+    // i64, as FPOWI has undefined result if the exponent is larger than i32).
+    if (Subtarget.is64Bit()) {
+      SDValue Exponent = DAG.getNode(ISD::SINT_TO_FP, SDLoc(N),
+                                     N->getValueType(0),
+                                     N->getOperand(1));
+      return DAG.getNode(ISD::FPOW, SDLoc(N),
+                         N->getValueType(0), N->getOperand(0), Exponent);
+    }
+    break;
+  }
   }
 
   return SDValue();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D102918.347011.patch
Type: text/x-patch
Size: 3580 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210521/1a01cf78/attachment.bin>


More information about the llvm-commits mailing list