[llvm] [Xtensa] Don't convert a select of FP constants into an indexed const… (PR #214974)

Omid Safarzadeh via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 8 08:18:52 PDT 2026


https://github.com/Bellman281 updated https://github.com/llvm/llvm-project/pull/214974

>From 62f9709b25812629dc1b256ddf8c5dbd688f6f8e Mon Sep 17 00:00:00 2001
From: Omid Safarzadeh <omidpoly at gmail.com>
Date: Sat, 8 Aug 2026 18:10:11 +0300
Subject: [PATCH 1/2] [Xtensa] Don't convert a select of FP constants into an
 indexed constant pool load

[Xtensa] Don't convert a select of FP constants into an indexed constant pool load
---
 llvm/lib/Target/Xtensa/XtensaISelLowering.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.h b/llvm/lib/Target/Xtensa/XtensaISelLowering.h
index 0d455919cb407..0a7a603aae915 100644
--- a/llvm/lib/Target/Xtensa/XtensaISelLowering.h
+++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.h
@@ -51,6 +51,16 @@ class XtensaTargetLowering : public TargetLowering {
 
   bool isFPImmLegal(const APFloat &Imm, EVT VT,
                     bool ForCodeSize) const override;
+  /// Xtensa reads constant pool entries with L32R, which loads the *contents*
+  /// of a PC-relative literal. There is no instruction that materializes the
+  /// address of a literal, so a constant pool base plus a variable offset
+  /// cannot be selected. Keep DAGCombiner from turning a select of two FP
+  /// constants into such an indexed constant pool load. Doing so would also be
+  /// a pessimization here: the branch it replaces is cheaper than the extra
+  /// address arithmetic and load.
+  bool reduceSelectOfFPConstantLoads(EVT CmpOpVT) const override {
+    return false;
+  }
 
   std::pair<unsigned, const TargetRegisterClass *>
   getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,

>From 7cbd827d33297ac95686badb5132129382fa83d7 Mon Sep 17 00:00:00 2001
From: Omid Safarzadeh <omidpoly at gmail.com>
Date: Sat, 8 Aug 2026 18:18:43 +0300
Subject: [PATCH 2/2] Create select-fp-constants.ll

[Xtensa] Add regression test for select of FP constants
---
 .../CodeGen/Xtensa/select-fp-constants.ll     | 45 +++++++++++++++++++
 1 file changed, 45 insertions(+)
 create mode 100644 llvm/test/CodeGen/Xtensa/select-fp-constants.ll

diff --git a/llvm/test/CodeGen/Xtensa/select-fp-constants.ll b/llvm/test/CodeGen/Xtensa/select-fp-constants.ll
new file mode 100644
index 0000000000000..652e046e7a94e
--- /dev/null
+++ b/llvm/test/CodeGen/Xtensa/select-fp-constants.ll
@@ -0,0 +1,45 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=xtensa -mattr=+fp -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s
+
+; A select between two FP constants must not be turned into a constant pool
+; load indexed by the condition. Xtensa reads literals with L32R, which loads
+; the contents of a PC-relative literal, so a constant pool base plus a
+; variable offset has no selectable form.
+
+define float @select_fp_constants(float %x) nounwind {
+; CHECK-LABEL: select_fp_constants:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    or a8, a2, a2
+; CHECK-NEXT:    l32r a2, .LCPI0_1
+; CHECK-NEXT:    wfr f8, a2
+; CHECK-NEXT:    wfr f9, a8
+; CHECK-NEXT:    olt.s b0, f9, f8
+; CHECK-NEXT:    bf b0, .LBB0_2
+; CHECK-NEXT:  # %bb.1:
+; CHECK-NEXT:    l32r a2, .LCPI0_0
+; CHECK-NEXT:  .LBB0_2:
+; CHECK-NEXT:    ret
+  %cmp = fcmp olt float %x, 0.000000e+00
+  %sel = select i1 %cmp, float -1.000000e+00, float 0.000000e+00
+  ret float %sel
+}
+
+define float @select_fp_constants_commuted(float %x) nounwind {
+; CHECK-LABEL: select_fp_constants_commuted:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    l32r a8, .LCPI1_2
+; CHECK-NEXT:    wfr f8, a8
+; CHECK-NEXT:    wfr f9, a2
+; CHECK-NEXT:    ule.s b0, f9, f8
+; CHECK-NEXT:    bf b0, .LBB1_2
+; CHECK-NEXT:  # %bb.1:
+; CHECK-NEXT:    l32r a2, .LCPI1_0
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB1_2:
+; CHECK-NEXT:    l32r a2, .LCPI1_1
+; CHECK-NEXT:    ret
+  %cmp = fcmp ogt float %x, 0.000000e+00
+  %sel = select i1 %cmp, float 1.000000e+00, float 2.500000e+00
+  ret float %sel
+}



More information about the llvm-commits mailing list