[llvm] [InstCombine] InstCombine should fold frexp of select to select of frexp (PR #121227)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 2 11:48:52 PST 2025


https://github.com/vortex73 updated https://github.com/llvm/llvm-project/pull/121227

>From 71bc166c27f818c803eaf16d7d73df670dd02f14 Mon Sep 17 00:00:00 2001
From: Narayan Sreekumar <nsreekumar6 at gmail.com>
Date: Thu, 2 Jan 2025 01:48:28 +0530
Subject: [PATCH] [InstCombine] Frexp-Select fold pre-commit tests

---
 .../InstCombine/InstructionCombining.cpp      |  2 +
 .../Transforms/InstCombine/select_frexp.ll    | 67 +++++++++++++++++++
 2 files changed, 69 insertions(+)
 create mode 100644 llvm/test/Transforms/InstCombine/select_frexp.ll

diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 934156f04f7fdd..ec74716f32f71e 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -4053,6 +4053,8 @@ Instruction *InstCombinerImpl::visitExtractValueInst(ExtractValueInst &EV) {
                                           SQ.getWithInstruction(&EV)))
     return replaceInstUsesWith(EV, V);
 
+
+
   if (InsertValueInst *IV = dyn_cast<InsertValueInst>(Agg)) {
     // We're extracting from an insertvalue instruction, compare the indices
     const unsigned *exti, *exte, *insi, *inse;
diff --git a/llvm/test/Transforms/InstCombine/select_frexp.ll b/llvm/test/Transforms/InstCombine/select_frexp.ll
new file mode 100644
index 00000000000000..5ff6d1867a73bb
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/select_frexp.ll
@@ -0,0 +1,67 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+declare { float, i32 } @llvm.frexp.f32.i32(float)
+
+; Basic case - constant in true position
+define float @test_select_frexp(float %x, i1 %cond) {
+; CHECK-LABEL: define float @test_select_frexp(
+; CHECK-SAME: float [[X:%.*]], i1 [[COND:%.*]]) {
+; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], float 1.000000e+00, float [[X]]
+; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[SEL]])
+; CHECK-NEXT:    [[FREXP_0:%.*]] = extractvalue { float, i32 } [[FREXP]], 0
+; CHECK-NEXT:    ret float [[FREXP_0]]
+;
+  %sel = select i1 %cond, float 1.000000e+00, float %x
+  %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %sel)
+  %frexp.0 = extractvalue { float, i32 } %frexp, 0
+  ret float %frexp.0
+}
+
+; Test with negative constant
+define float @test_select_frexp_negative(float %x, i1 %cond) {
+; CHECK-LABEL: define float @test_select_frexp_negative(
+; CHECK-SAME: float [[X:%.*]], i1 [[COND:%.*]]) {
+; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], float -1.000000e+00, float [[X]]
+; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[SEL]])
+; CHECK-NEXT:    [[FREXP_0:%.*]] = extractvalue { float, i32 } [[FREXP]], 0
+; CHECK-NEXT:    ret float [[FREXP_0]]
+;
+  %sel = select i1 %cond, float -1.000000e+00, float %x
+  %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %sel)
+  %frexp.0 = extractvalue { float, i32 } %frexp, 0
+  ret float %frexp.0
+}
+
+; Test with constant in false position
+define float @test_select_frexp_false_const(float %x, i1 %cond) {
+; CHECK-LABEL: define float @test_select_frexp_false_const(
+; CHECK-SAME: float [[X:%.*]], i1 [[COND:%.*]]) {
+; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], float [[X]], float 1.000000e+00
+; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[SEL]])
+; CHECK-NEXT:    [[FREXP_0:%.*]] = extractvalue { float, i32 } [[FREXP]], 0
+; CHECK-NEXT:    ret float [[FREXP_0]]
+;
+  %sel = select i1 %cond, float %x, float 1.000000e+00
+  %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %sel)
+  %frexp.0 = extractvalue { float, i32 } %frexp, 0
+  ret float %frexp.0
+}
+
+; Multiple uses of extract - should not optimize
+define float @test_select_frexp_multi_use(float %x, i1 %cond) {
+; CHECK-LABEL: define float @test_select_frexp_multi_use(
+; CHECK-SAME: float [[X:%.*]], i1 [[COND:%.*]]) {
+; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], float 1.000000e+00, float [[X]]
+; CHECK-NEXT:    [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[SEL]])
+; CHECK-NEXT:    [[FREXP_0:%.*]] = extractvalue { float, i32 } [[FREXP]], 0
+; CHECK-NEXT:    [[RES:%.*]] = fadd float [[FREXP_0]], 1.000000e+00
+; CHECK-NEXT:    ret float [[RES]]
+;
+  %sel = select i1 %cond, float 1.000000e+00, float %x
+  %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %sel)
+  %frexp.0 = extractvalue { float, i32 } %frexp, 0
+  %frexp.1 = extractvalue { float, i32 } %frexp, 1
+  %res = fadd float %frexp.0, 1.0
+  ret float %res
+}



More information about the llvm-commits mailing list