[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