[llvm] [InstCombine] foldFPSignBitOps - fabs(X) * fabs(X) -> freeze(X) * freeze(X) (PR #120072)
Simon Pilgrim via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 16 04:22:59 PST 2024
https://github.com/RKSimon created https://github.com/llvm/llvm-project/pull/120072
Ensure we freeze the repeated X operand as we are increasing its number of uses.
Reported on Project Zero: https://web.ist.utl.pt/nuno.lopes/alive2/index.php?hash=de3d864b2cd8f709&test=Transforms%2FInstCombine%2Ffmul.ll
>From 2ab035342fb97b470a0db5acf23b205a092c7efb Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Mon, 16 Dec 2024 12:21:19 +0000
Subject: [PATCH] [InstCombine] foldFPSignBitOps - fabs(X) * fabs(X) ->
freeze(X) * freeze(X)
Ensure we freeze the repeated X operand as we are increasing its number of uses.
Reported on Project Zero: https://web.ist.utl.pt/nuno.lopes/alive2/index.php?hash=de3d864b2cd8f709&test=Transforms%2FInstCombine%2Ffmul.ll
---
llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | 9 +++++++--
llvm/test/Transforms/InstCombine/fdiv.ll | 6 ++++--
llvm/test/Transforms/InstCombine/fmul.ll | 6 ++++--
3 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index f85a3c93651353..519e7968a5e1d5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -583,8 +583,13 @@ Instruction *InstCombinerImpl::foldFPSignBitOps(BinaryOperator &I) {
// fabs(X) * fabs(X) -> X * X
// fabs(X) / fabs(X) -> X / X
- if (Op0 == Op1 && match(Op0, m_FAbs(m_Value(X))))
- return BinaryOperator::CreateWithCopiedFlags(Opcode, X, X, &I);
+ // X must be frozen because we are increasing its number of uses.
+ if (Op0 == Op1 && match(Op0, m_FAbs(m_Value(X)))) {
+ Value *FX = X;
+ if (!isGuaranteedNotToBeUndef(X))
+ FX = Builder.CreateFreeze(X, X->getName() + ".fr");
+ return BinaryOperator::CreateWithCopiedFlags(Opcode, FX, FX, &I);
+ }
// fabs(X) * fabs(Y) --> fabs(X * Y)
// fabs(X) / fabs(Y) --> fabs(X / Y)
diff --git a/llvm/test/Transforms/InstCombine/fdiv.ll b/llvm/test/Transforms/InstCombine/fdiv.ll
index 54b0bf8c50ac70..f7f0ad5f468cb1 100644
--- a/llvm/test/Transforms/InstCombine/fdiv.ll
+++ b/llvm/test/Transforms/InstCombine/fdiv.ll
@@ -593,7 +593,8 @@ define float @fdiv_fneg1_extra_use(float %x, float %y) {
define float @fabs_same_op(float %x) {
; CHECK-LABEL: @fabs_same_op(
-; CHECK-NEXT: [[R:%.*]] = fdiv float [[X:%.*]], [[X]]
+; CHECK-NEXT: [[X:%.*]] = freeze float [[X1:%.*]]
+; CHECK-NEXT: [[R:%.*]] = fdiv float [[X]], [[X]]
; CHECK-NEXT: ret float [[R]]
;
%a = call float @llvm.fabs.f32(float %x)
@@ -603,7 +604,8 @@ define float @fabs_same_op(float %x) {
define float @fabs_same_op_extra_use(float %x) {
; CHECK-LABEL: @fabs_same_op_extra_use(
-; CHECK-NEXT: [[A:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
+; CHECK-NEXT: [[X:%.*]] = freeze float [[X1:%.*]]
+; CHECK-NEXT: [[A:%.*]] = call float @llvm.fabs.f32(float [[X]])
; CHECK-NEXT: call void @use_f32(float [[A]])
; CHECK-NEXT: [[R:%.*]] = fdiv reassoc ninf float [[X]], [[X]]
; CHECK-NEXT: ret float [[R]]
diff --git a/llvm/test/Transforms/InstCombine/fmul.ll b/llvm/test/Transforms/InstCombine/fmul.ll
index cd4a8e36c6e239..bd91f32e195d56 100644
--- a/llvm/test/Transforms/InstCombine/fmul.ll
+++ b/llvm/test/Transforms/InstCombine/fmul.ll
@@ -463,7 +463,8 @@ declare float @llvm.fabs.f32(float) nounwind readnone
define float @fabs_squared(float %x) {
; CHECK-LABEL: @fabs_squared(
-; CHECK-NEXT: [[MUL:%.*]] = fmul float [[X:%.*]], [[X]]
+; CHECK-NEXT: [[X:%.*]] = freeze float [[X1:%.*]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul float [[X]], [[X]]
; CHECK-NEXT: ret float [[MUL]]
;
%x.fabs = call float @llvm.fabs.f32(float %x)
@@ -473,7 +474,8 @@ define float @fabs_squared(float %x) {
define float @fabs_squared_fast(float %x) {
; CHECK-LABEL: @fabs_squared_fast(
-; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[X:%.*]], [[X]]
+; CHECK-NEXT: [[X:%.*]] = freeze float [[X1:%.*]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[X]], [[X]]
; CHECK-NEXT: ret float [[MUL]]
;
%x.fabs = call float @llvm.fabs.f32(float %x)
More information about the llvm-commits
mailing list