[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