[llvm] f7f5d34 - InstCombine: Fold fneg (ldexp x, n) -> ldexp (fneg x), n
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 11 16:16:32 PDT 2023
Author: Matt Arsenault
Date: 2023-08-11T19:16:20-04:00
New Revision: f7f5d348a315d96c907b57e6cafea4cbcb620340
URL: https://github.com/llvm/llvm-project/commit/f7f5d348a315d96c907b57e6cafea4cbcb620340
DIFF: https://github.com/llvm/llvm-project/commit/f7f5d348a315d96c907b57e6cafea4cbcb620340.diff
LOG: InstCombine: Fold fneg (ldexp x, n) -> ldexp (fneg x), n
https://reviews.llvm.org/D156579
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
llvm/lib/Transforms/InstCombine/InstCombineInternal.h
llvm/test/Transforms/InstCombine/fneg.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index ee5329d9bc68d8..c0afcc90d8337f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2557,17 +2557,35 @@ static Instruction *foldFNegIntoConstant(Instruction &I, const DataLayout &DL) {
return nullptr;
}
-static Instruction *hoistFNegAboveFMulFDiv(Value *FNegOp,
- Instruction &FMFSource,
- InstCombiner::BuilderTy &Builder) {
+Instruction *InstCombinerImpl::hoistFNegAboveFMulFDiv(Value *FNegOp,
+ Instruction &FMFSource) {
Value *X, *Y;
- if (match(FNegOp, m_FMul(m_Value(X), m_Value(Y))))
- return BinaryOperator::CreateFMulFMF(Builder.CreateFNegFMF(X, &FMFSource),
- Y, &FMFSource);
+ if (match(FNegOp, m_FMul(m_Value(X), m_Value(Y)))) {
+ return cast<Instruction>(Builder.CreateFMulFMF(
+ Builder.CreateFNegFMF(X, &FMFSource), Y, &FMFSource));
+ }
+
+ if (match(FNegOp, m_FDiv(m_Value(X), m_Value(Y)))) {
+ return cast<Instruction>(Builder.CreateFDivFMF(
+ Builder.CreateFNegFMF(X, &FMFSource), Y, &FMFSource));
+ }
+
+ if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(FNegOp)) {
+ // Make sure to preserve flags and metadata on the call.
+ if (II->getIntrinsicID() == Intrinsic::ldexp) {
+ FastMathFlags FMF = FMFSource.getFastMathFlags();
+ FMF |= II->getFastMathFlags();
- if (match(FNegOp, m_FDiv(m_Value(X), m_Value(Y))))
- return BinaryOperator::CreateFDivFMF(Builder.CreateFNegFMF(X, &FMFSource),
- Y, &FMFSource);
+ IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);
+ Builder.setFastMathFlags(FMF);
+
+ CallInst *New = Builder.CreateCall(
+ II->getCalledFunction(),
+ {Builder.CreateFNeg(II->getArgOperand(0)), II->getArgOperand(1)});
+ New->copyMetadata(*II);
+ return New;
+ }
+ }
return nullptr;
}
@@ -2593,8 +2611,8 @@ Instruction *InstCombinerImpl::visitFNeg(UnaryOperator &I) {
if (!match(Op, m_OneUse(m_Value(OneUse))))
return nullptr;
- if (Instruction *R = hoistFNegAboveFMulFDiv(OneUse, I, Builder))
- return R;
+ if (Instruction *R = hoistFNegAboveFMulFDiv(OneUse, I))
+ return replaceInstUsesWith(I, R);
// Try to eliminate fneg if at least 1 arm of the select is negated.
Value *Cond;
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
index 9d50e5b3a4ba44..7e9b916783a0e7 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
+++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -392,6 +392,8 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
Instruction *foldAndOrOfSelectUsingImpliedCond(Value *Op, SelectInst &SI,
bool IsAnd);
+ Instruction *hoistFNegAboveFMulFDiv(Value *FNegOp, Instruction &FMFSource);
+
public:
/// Create and insert the idiom we use to indicate a block is unreachable
/// without having to rewrite the CFG from within InstCombine.
diff --git a/llvm/test/Transforms/InstCombine/fneg.ll b/llvm/test/Transforms/InstCombine/fneg.ll
index d9047ad53e814a..ed68ba50d36ee9 100644
--- a/llvm/test/Transforms/InstCombine/fneg.ll
+++ b/llvm/test/Transforms/InstCombine/fneg.ll
@@ -834,8 +834,8 @@ define float @select_fneg_use3(float %x, float %y, i1 %b) {
define float @fneg_ldexp(float %x, i32 %n) {
; CHECK-LABEL: @fneg_ldexp(
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]])
-; CHECK-NEXT: [[NEG:%.*]] = fneg float [[LDEXP]]
+; CHECK-NEXT: [[TMP1:%.*]] = fneg float [[X:%.*]]
+; CHECK-NEXT: [[NEG:%.*]] = call float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]])
; CHECK-NEXT: ret float [[NEG]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n)
@@ -845,8 +845,8 @@ define float @fneg_ldexp(float %x, i32 %n) {
define float @fsub_fneg_ldexp(float %x, i32 %n) {
; CHECK-LABEL: @fsub_fneg_ldexp(
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]])
-; CHECK-NEXT: [[NEG:%.*]] = fneg float [[LDEXP]]
+; CHECK-NEXT: [[TMP1:%.*]] = fneg float [[X:%.*]]
+; CHECK-NEXT: [[NEG:%.*]] = call float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]])
; CHECK-NEXT: ret float [[NEG]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n)
@@ -856,8 +856,8 @@ define float @fsub_fneg_ldexp(float %x, i32 %n) {
define float @fsub_fneg_ldexp_nsz(float %x, i32 %n) {
; CHECK-LABEL: @fsub_fneg_ldexp_nsz(
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]])
-; CHECK-NEXT: [[NEG:%.*]] = fneg nsz float [[LDEXP]]
+; CHECK-NEXT: [[TMP1:%.*]] = fneg nsz float [[X:%.*]]
+; CHECK-NEXT: [[NEG:%.*]] = call nsz float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]])
; CHECK-NEXT: ret float [[NEG]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n)
@@ -867,8 +867,8 @@ define float @fsub_fneg_ldexp_nsz(float %x, i32 %n) {
define float @fsub_fneg_ldexp_p0_nsz(float %x, i32 %n) {
; CHECK-LABEL: @fsub_fneg_ldexp_p0_nsz(
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]])
-; CHECK-NEXT: [[NEG:%.*]] = fneg nsz float [[LDEXP]]
+; CHECK-NEXT: [[TMP1:%.*]] = fneg nsz float [[X:%.*]]
+; CHECK-NEXT: [[NEG:%.*]] = call nsz float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]])
; CHECK-NEXT: ret float [[NEG]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n)
@@ -889,8 +889,8 @@ define float @fsub_fneg_ldexp_p0(float %x, i32 %n) {
define <2 x float> @fneg_ldexp_vector(<2 x float> %x, <2 x i32> %n) {
; CHECK-LABEL: @fneg_ldexp_vector(
-; CHECK-NEXT: [[LDEXP:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X:%.*]], <2 x i32> [[N:%.*]])
-; CHECK-NEXT: [[NEG:%.*]] = fneg <2 x float> [[LDEXP]]
+; CHECK-NEXT: [[TMP1:%.*]] = fneg <2 x float> [[X:%.*]]
+; CHECK-NEXT: [[NEG:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[TMP1]], <2 x i32> [[N:%.*]])
; CHECK-NEXT: ret <2 x float> [[NEG]]
;
%ldexp = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> %n)
@@ -913,8 +913,8 @@ define float @fneg_ldexp_multiuse(float %x, i32 %n, ptr %ptr) {
define float @fneg_ldexp_fmf_ldexp(float %x, i32 %n) {
; CHECK-LABEL: @fneg_ldexp_fmf_ldexp(
-; CHECK-NEXT: [[LDEXP:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]])
-; CHECK-NEXT: [[NEG:%.*]] = fneg float [[LDEXP]]
+; CHECK-NEXT: [[TMP1:%.*]] = fneg nnan float [[X:%.*]]
+; CHECK-NEXT: [[NEG:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]])
; CHECK-NEXT: ret float [[NEG]]
;
%ldexp = call nnan float @llvm.ldexp.f32.i32(float %x, i32 %n)
@@ -924,8 +924,8 @@ define float @fneg_ldexp_fmf_ldexp(float %x, i32 %n) {
define float @fneg_ldexp_fmf_neg(float %x, i32 %n) {
; CHECK-LABEL: @fneg_ldexp_fmf_neg(
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]])
-; CHECK-NEXT: [[NEG:%.*]] = fneg nnan float [[LDEXP]]
+; CHECK-NEXT: [[TMP1:%.*]] = fneg nnan float [[X:%.*]]
+; CHECK-NEXT: [[NEG:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]])
; CHECK-NEXT: ret float [[NEG]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n)
@@ -935,8 +935,8 @@ define float @fneg_ldexp_fmf_neg(float %x, i32 %n) {
define float @fneg_ldexp_fmf(float %x, i32 %n) {
; CHECK-LABEL: @fneg_ldexp_fmf(
-; CHECK-NEXT: [[LDEXP:%.*]] = call ninf float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]])
-; CHECK-NEXT: [[NEG:%.*]] = fneg nnan float [[LDEXP]]
+; CHECK-NEXT: [[TMP1:%.*]] = fneg nnan ninf float [[X:%.*]]
+; CHECK-NEXT: [[NEG:%.*]] = call nnan ninf float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]])
; CHECK-NEXT: ret float [[NEG]]
;
%ldexp = call ninf float @llvm.ldexp.f32.i32(float %x, i32 %n)
@@ -946,8 +946,8 @@ define float @fneg_ldexp_fmf(float %x, i32 %n) {
define float @fneg_ldexp_contract0(float %x, i32 %n) {
; CHECK-LABEL: @fneg_ldexp_contract0(
-; CHECK-NEXT: [[LDEXP:%.*]] = call contract float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]])
-; CHECK-NEXT: [[NEG:%.*]] = fneg float [[LDEXP]]
+; CHECK-NEXT: [[TMP1:%.*]] = fneg contract float [[X:%.*]]
+; CHECK-NEXT: [[NEG:%.*]] = call contract float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]])
; CHECK-NEXT: ret float [[NEG]]
;
%ldexp = call contract float @llvm.ldexp.f32.i32(float %x, i32 %n)
@@ -957,8 +957,8 @@ define float @fneg_ldexp_contract0(float %x, i32 %n) {
define float @fneg_ldexp_contract1(float %x, i32 %n) {
; CHECK-LABEL: @fneg_ldexp_contract1(
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]])
-; CHECK-NEXT: [[NEG:%.*]] = fneg contract float [[LDEXP]]
+; CHECK-NEXT: [[TMP1:%.*]] = fneg contract float [[X:%.*]]
+; CHECK-NEXT: [[NEG:%.*]] = call contract float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]])
; CHECK-NEXT: ret float [[NEG]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n)
@@ -968,8 +968,8 @@ define float @fneg_ldexp_contract1(float %x, i32 %n) {
define float @fneg_ldexp_contract(float %x, i32 %n) {
; CHECK-LABEL: @fneg_ldexp_contract(
-; CHECK-NEXT: [[LDEXP:%.*]] = call contract float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]])
-; CHECK-NEXT: [[NEG:%.*]] = fneg contract float [[LDEXP]]
+; CHECK-NEXT: [[TMP1:%.*]] = fneg contract float [[X:%.*]]
+; CHECK-NEXT: [[NEG:%.*]] = call contract float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]])
; CHECK-NEXT: ret float [[NEG]]
;
%ldexp = call contract float @llvm.ldexp.f32.i32(float %x, i32 %n)
@@ -979,8 +979,8 @@ define float @fneg_ldexp_contract(float %x, i32 %n) {
define float @fneg_ldexp_metadata(float %x, i32 %n) {
; CHECK-LABEL: @fneg_ldexp_metadata(
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]), !arst !0
-; CHECK-NEXT: [[NEG:%.*]] = fneg float [[LDEXP]]
+; CHECK-NEXT: [[TMP1:%.*]] = fneg float [[X:%.*]]
+; CHECK-NEXT: [[NEG:%.*]] = call float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[N:%.*]]), !arst !0
; CHECK-NEXT: ret float [[NEG]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n), !arst !0
More information about the llvm-commits
mailing list