[llvm] DAG: Fix asserting in error case for powi softening (PR #147237)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 6 23:42:35 PDT 2025


https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/147237

>From 1db2f3e0946d37f3feecb7bb7a752740cec5d027 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Mon, 7 Jul 2025 14:12:34 +0900
Subject: [PATCH] DAG: Fix asserting in error case for powi softening

We need to return the expected legalized type, not the original
in this case. Also swap to returning poison, and avoid contraction
in error message.

For some reason the strictfp version of powi hardcodes i32 as
the int type, so use an msp430 test to test the strict case where
int is i16.
---
 .../CodeGen/SelectionDAG/LegalizeFloatTypes.cpp | 17 +++++++++--------
 .../CodeGen/ARM/powi-soften-libcall-error.ll    |  8 ++++++++
 .../CodeGen/MSP430/powi-soften-libcall-error.ll | 16 ++++++++++++++++
 3 files changed, 33 insertions(+), 8 deletions(-)
 create mode 100644 llvm/test/CodeGen/ARM/powi-soften-libcall-error.ll
 create mode 100644 llvm/test/CodeGen/MSP430/powi-soften-libcall-error.ll

diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index 7dfb43164be37..d96e9a367aab7 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -715,11 +715,9 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FPOW(SDNode *N) {
 SDValue DAGTypeLegalizer::SoftenFloatRes_ExpOp(SDNode *N) {
   bool IsStrict = N->isStrictFPOpcode();
   unsigned Offset = IsStrict ? 1 : 0;
-  assert((N->getOperand(1 + Offset).getValueType() == MVT::i16 ||
-          N->getOperand(1 + Offset).getValueType() == MVT::i32) &&
-         "Unsupported power type!");
   bool IsPowI =
       N->getOpcode() == ISD::FPOWI || N->getOpcode() == ISD::STRICT_FPOWI;
+  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
 
   RTLIB::Libcall LC = IsPowI ? RTLIB::getPOWI(N->getValueType(0))
                              : RTLIB::getLDEXP(N->getValueType(0));
@@ -727,19 +725,22 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_ExpOp(SDNode *N) {
   if (!TLI.getLibcallName(LC)) {
     // Some targets don't have a powi libcall; use pow instead.
     // FIXME: Implement this if some target needs it.
-    DAG.getContext()->emitError("Don't know how to soften fpowi to fpow");
-    return DAG.getUNDEF(N->getValueType(0));
+    DAG.getContext()->emitError("do not know how to soften fpowi to fpow");
+    if (IsStrict)
+      ReplaceValueWith(SDValue(N, 1), N->getOperand(0));
+    return DAG.getPOISON(NVT);
   }
 
   if (DAG.getLibInfo().getIntSize() !=
       N->getOperand(1 + Offset).getValueType().getSizeInBits()) {
     // If the exponent does not match with sizeof(int) a libcall to RTLIB::POWI
     // would use the wrong type for the argument.
-    DAG.getContext()->emitError("POWI exponent does not match sizeof(int)");
-    return DAG.getUNDEF(N->getValueType(0));
+    DAG.getContext()->emitError("powi exponent does not match sizeof(int)");
+    if (IsStrict)
+      ReplaceValueWith(SDValue(N, 1), N->getOperand(0));
+    return DAG.getPOISON(NVT);
   }
 
-  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
   SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0 + Offset)),
                      N->getOperand(1 + Offset) };
   SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
diff --git a/llvm/test/CodeGen/ARM/powi-soften-libcall-error.ll b/llvm/test/CodeGen/ARM/powi-soften-libcall-error.ll
new file mode 100644
index 0000000000000..1feb544d42e74
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/powi-soften-libcall-error.ll
@@ -0,0 +1,8 @@
+; RUN: not llc -mtriple=arm-linux-gnu -float-abi=soft -filetype=null %s 2>&1 | FileCheck %s
+
+; FIXME: This should not fail but isn't implemented
+; CHECK: error: powi exponent does not match sizeof(int)
+define float @soften_powi_error(float %x, i64 %n) {
+  %powi = call float @llvm.powi.f32.i64(float %x, i64 %n)
+  ret float %powi
+}
diff --git a/llvm/test/CodeGen/MSP430/powi-soften-libcall-error.ll b/llvm/test/CodeGen/MSP430/powi-soften-libcall-error.ll
new file mode 100644
index 0000000000000..b0fbdc6717612
--- /dev/null
+++ b/llvm/test/CodeGen/MSP430/powi-soften-libcall-error.ll
@@ -0,0 +1,16 @@
+; RUN: not llc -mtriple=msp430 -filetype=null %s 2>&1 | FileCheck %s
+
+; FIXME: This should not fail but isn't implemented
+; CHECK: error: powi exponent does not match sizeof(int)
+define float @soften_powi_error(float %x, i32 %n) {
+  %powi = call float @llvm.powi.f32.i32(float %x, i32 %n)
+  ret float %powi
+}
+
+; CHECK: error: powi exponent does not match sizeof(int)
+define float @soften_powi_error_strictfp(float %x, i32 %n) strictfp {
+ %powi = call float @llvm.experimental.constrained.powi.f32.i32(float %x, i32 %n, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret float %powi
+}
+
+



More information about the llvm-commits mailing list