[llvm] InstCombine: Try to fold ldexp with select of power operand (PR #97354)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 2 04:32:11 PDT 2024


https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/97354

>From 30cbe8b03efd589c8c96e5beee37b5e1f8298803 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Fri, 11 Nov 2022 21:52:08 -0800
Subject: [PATCH 1/4] InstCombine: Add baseline checks for ldexp(x, c ? x : 0)
 combine

---
 llvm/test/Transforms/InstCombine/ldexp.ll | 128 +++++++++++++++++++++-
 1 file changed, 127 insertions(+), 1 deletion(-)

diff --git a/llvm/test/Transforms/InstCombine/ldexp.ll b/llvm/test/Transforms/InstCombine/ldexp.ll
index 3ede7d913b525..4c618b861cc08 100644
--- a/llvm/test/Transforms/InstCombine/ldexp.ll
+++ b/llvm/test/Transforms/InstCombine/ldexp.ll
@@ -870,7 +870,7 @@ define float @ldexp_2_flags(float %x) {
 define float @ldexp_metadata(float %x) {
 ; CHECK-LABEL: define float @ldexp_metadata
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 2), !foo !2
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 2), !foo [[META2:![0-9]+]]
 ; CHECK-NEXT:    ret float [[LDEXP]]
 ;
   %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 2), !foo !2
@@ -889,6 +889,132 @@ define float @ldexp_8_contractable(float %x, float %y) {
   ret float %fadd
 }
 
+define float @ldexp_f32_mask_select_0(i1 %cond, float %x, i32 %y) {
+; CHECK-LABEL: define float @ldexp_f32_mask_select_0
+; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], i32 [[Y]], i32 0
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[SELECT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %select = select i1 %cond, i32 %y, i32 0
+  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %select)
+  ret float %ldexp
+}
+
+define float @ldexp_nnan_f32_mask_select_0(i1 %cond, float %x, i32 %y) {
+; CHECK-LABEL: define float @ldexp_nnan_f32_mask_select_0
+; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], i32 [[Y]], i32 0
+; CHECK-NEXT:    [[LDEXP:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[X]], i32 [[SELECT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %select = select i1 %cond, i32 %y, i32 0
+  %ldexp = call nnan float @llvm.ldexp.f32.i32(float %x, i32 %select)
+  ret float %ldexp
+}
+
+define float @ldexp_flags_f32_mask_select_0(i1 %cond, float %x, i32 %y) {
+; CHECK-LABEL: define float @ldexp_flags_f32_mask_select_0
+; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], i32 [[Y]], i32 0
+; CHECK-NEXT:    [[LDEXP:%.*]] = call ninf nsz float @llvm.ldexp.f32.i32(float [[X]], i32 [[SELECT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %select = select i1 %cond, i32 %y, i32 0
+  %ldexp = call nsz ninf float @llvm.ldexp.f32.i32(float %x, i32 %select)
+  ret float %ldexp
+}
+
+define float @ldexp_f32_mask_select_0_swap(i1 %cond, float %x, i32 %y) {
+; CHECK-LABEL: define float @ldexp_f32_mask_select_0_swap
+; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], i32 0, i32 [[Y]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[SELECT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %select = select i1 %cond, i32 0, i32 %y
+  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %select)
+  ret float %ldexp
+}
+
+define float @ldexp_f32_mask_select_1(i1 %cond, float %x, i32 %y) {
+; CHECK-LABEL: define float @ldexp_f32_mask_select_1
+; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], i32 [[Y]], i32 1
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[SELECT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %select = select i1 %cond, i32 %y, i32 1
+  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %select)
+  ret float %ldexp
+}
+
+define float @ldexp_f32_mask_select_0_multi_use(i1 %cond, float %x, i32 %y, ptr %ptr) {
+; CHECK-LABEL: define float @ldexp_f32_mask_select_0_multi_use
+; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]], ptr [[PTR:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], i32 [[Y]], i32 0
+; CHECK-NEXT:    store i32 [[SELECT]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[SELECT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %select = select i1 %cond, i32 %y, i32 0
+  store i32 %select, ptr %ptr
+  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %select)
+  ret float %ldexp
+}
+
+define float @ldexp_f32_mask_select_0_swap_multi_use(i1 %cond, float %x, i32 %y, ptr %ptr) {
+; CHECK-LABEL: define float @ldexp_f32_mask_select_0_swap_multi_use
+; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]], ptr [[PTR:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], i32 0, i32 [[Y]]
+; CHECK-NEXT:    store i32 [[SELECT]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[SELECT]])
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %select = select i1 %cond, i32 0, i32 %y
+  store i32 %select, ptr %ptr
+  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %select)
+  ret float %ldexp
+}
+
+define float @ldexp_f32_mask_select_0_strictfp(i1 %cond, float %x, i32 %y) #0 {
+; CHECK-LABEL: define float @ldexp_f32_mask_select_0_strictfp
+; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]]) #[[ATTR1:[0-9]+]] {
+; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], i32 [[Y]], i32 0
+; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float [[X]], i32 [[SELECT]], metadata !"round.dynamic", metadata !"fpexcept.strict")
+; CHECK-NEXT:    ret float [[LDEXP]]
+;
+  %select = select i1 %cond, i32 %y, i32 0
+  %ldexp = call float @llvm.experimental.constrained.ldexp.f32.i32(float %x, i32 %select, metadata !"round.dynamic", metadata !"fpexcept.strict")
+  ret float %ldexp
+}
+
+define <2 x float> @ldexp_v2f32_mask_select_0(<2 x i1> %cond, <2 x float> %x, <2 x i32> %y) {
+; CHECK-LABEL: define <2 x float> @ldexp_v2f32_mask_select_0
+; CHECK-SAME: (<2 x i1> [[COND:%.*]], <2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select <2 x i1> [[COND]], <2 x i32> [[Y]], <2 x i32> zeroinitializer
+; CHECK-NEXT:    [[LDEXP:%.*]] = call nnan nsz <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> [[SELECT]])
+; CHECK-NEXT:    ret <2 x float> [[LDEXP]]
+;
+  %select = select <2 x i1> %cond, <2 x i32> %y, <2 x i32> zeroinitializer
+  %ldexp = call nsz nnan <2 x float> @llvm.ldexp.f32.v2i32(<2 x float> %x, <2 x i32> %select)
+  ret <2 x float> %ldexp
+}
+
+define <2 x float> @ldexp_v2f32_mask_select_0_swap(<2 x i1> %cond, <2 x float> %x, <2 x i32> %y) {
+; CHECK-LABEL: define <2 x float> @ldexp_v2f32_mask_select_0_swap
+; CHECK-SAME: (<2 x i1> [[COND:%.*]], <2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
+; CHECK-NEXT:    [[SELECT:%.*]] = select <2 x i1> [[COND]], <2 x i32> zeroinitializer, <2 x i32> [[Y]]
+; CHECK-NEXT:    [[LDEXP:%.*]] = call nnan nsz <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> [[SELECT]])
+; CHECK-NEXT:    ret <2 x float> [[LDEXP]]
+;
+  %select = select <2 x i1> %cond, <2 x i32> zeroinitializer, <2 x i32> %y
+  %ldexp = call nsz nnan <2 x float> @llvm.ldexp.f32.v2i32(<2 x float> %x, <2 x i32> %select)
+  ret <2 x float> %ldexp
+}
+
+attributes #0 = { strictfp }
+
 !0 = !{i32 -127, i32 0}
 !1 = !{i32 0, i32 127}
 !2 = !{}

>From 672b19972c7aedd013f19ec40de987325f2ca28e Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Tue, 26 May 2020 21:05:47 -0400
Subject: [PATCH 2/4] InstCombine: Try to fold ldexp with select of power
 operand

This makes it more likely a constant value can fold into the source
operand.
---
 llvm/include/llvm/IR/IRBuilder.h              |  7 ++++++
 .../InstCombine/InstCombineCalls.cpp          | 25 +++++++++++++++++++
 llvm/test/Transforms/InstCombine/ldexp.ll     | 24 +++++++++---------
 3 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h
index f81cfc0dce972..d4b7f21b60a4b 100644
--- a/llvm/include/llvm/IR/IRBuilder.h
+++ b/llvm/include/llvm/IR/IRBuilder.h
@@ -1023,6 +1023,13 @@ class IRBuilderBase {
                                  Name);
   }
 
+  /// Create call to the ldexp intrinsic.
+  Value *CreateLdexp(Value *Src, Value *Exp, const Twine &Name = "") {
+    assert(!IsFPConstrained && "TODO: Support strictfp");
+    return CreateIntrinsic(Intrinsic::ldexp, {Src->getType(), Exp->getType()},
+                           {Src, Exp}, nullptr, Name);
+  }
+
   /// Create a call to the arithmetic_fence intrinsic.
   CallInst *CreateArithmeticFence(Value *Val, Type *DstType,
                                   const Twine &Name = "") {
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 9291e6e67ef71..b6642b8bd6a39 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2641,6 +2641,31 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
       return BinaryOperator::CreateFMulFMF(Src, Select, II);
     }
 
+    // ldexp(x, c ? exp : 0) -> c ? ldexp(x, exp) : x
+    // ldexp(x, c ? 0 : exp) -> c ? x : ldexp(x, exp)
+    ///
+    // TODO: If we cared, should insert a canonicalize for x
+    Value *SelectCond, *SelectLHS, *SelectRHS;
+    if (match(II->getArgOperand(1),
+              m_OneUse(m_Select(m_Value(SelectCond), m_Value(SelectLHS),
+                                m_Value(SelectRHS))))) {
+      Value *NewLdexp = nullptr;
+      Value *Select = nullptr;
+      if (match(SelectRHS, m_ZeroInt())) {
+        NewLdexp = Builder.CreateLdexp(Src, SelectLHS);
+        Select = Builder.CreateSelect(SelectCond, NewLdexp, Src);
+      } else if (match(SelectLHS, m_ZeroInt())) {
+        NewLdexp = Builder.CreateLdexp(Src, SelectRHS);
+        Select = Builder.CreateSelect(SelectCond, Src, NewLdexp);
+      }
+
+      if (NewLdexp) {
+        Select->takeName(II);
+        cast<Instruction>(NewLdexp)->copyIRFlags(II);
+        return replaceInstUsesWith(*II, Select);
+      }
+    }
+
     break;
   }
   case Intrinsic::ptrauth_auth:
diff --git a/llvm/test/Transforms/InstCombine/ldexp.ll b/llvm/test/Transforms/InstCombine/ldexp.ll
index 4c618b861cc08..7ae483cbda0e2 100644
--- a/llvm/test/Transforms/InstCombine/ldexp.ll
+++ b/llvm/test/Transforms/InstCombine/ldexp.ll
@@ -892,8 +892,8 @@ define float @ldexp_8_contractable(float %x, float %y) {
 define float @ldexp_f32_mask_select_0(i1 %cond, float %x, i32 %y) {
 ; CHECK-LABEL: define float @ldexp_f32_mask_select_0
 ; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], i32 [[Y]], i32 0
-; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[SELECT]])
+; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[Y]])
+; CHECK-NEXT:    [[LDEXP:%.*]] = select i1 [[COND]], float [[TMP1]], float [[X]]
 ; CHECK-NEXT:    ret float [[LDEXP]]
 ;
   %select = select i1 %cond, i32 %y, i32 0
@@ -904,8 +904,8 @@ define float @ldexp_f32_mask_select_0(i1 %cond, float %x, i32 %y) {
 define float @ldexp_nnan_f32_mask_select_0(i1 %cond, float %x, i32 %y) {
 ; CHECK-LABEL: define float @ldexp_nnan_f32_mask_select_0
 ; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], i32 [[Y]], i32 0
-; CHECK-NEXT:    [[LDEXP:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[X]], i32 [[SELECT]])
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[X]], i32 [[Y]])
+; CHECK-NEXT:    [[LDEXP:%.*]] = select i1 [[COND]], float [[TMP1]], float [[X]]
 ; CHECK-NEXT:    ret float [[LDEXP]]
 ;
   %select = select i1 %cond, i32 %y, i32 0
@@ -916,8 +916,8 @@ define float @ldexp_nnan_f32_mask_select_0(i1 %cond, float %x, i32 %y) {
 define float @ldexp_flags_f32_mask_select_0(i1 %cond, float %x, i32 %y) {
 ; CHECK-LABEL: define float @ldexp_flags_f32_mask_select_0
 ; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], i32 [[Y]], i32 0
-; CHECK-NEXT:    [[LDEXP:%.*]] = call ninf nsz float @llvm.ldexp.f32.i32(float [[X]], i32 [[SELECT]])
+; CHECK-NEXT:    [[TMP1:%.*]] = call ninf nsz float @llvm.ldexp.f32.i32(float [[X]], i32 [[Y]])
+; CHECK-NEXT:    [[LDEXP:%.*]] = select i1 [[COND]], float [[TMP1]], float [[X]]
 ; CHECK-NEXT:    ret float [[LDEXP]]
 ;
   %select = select i1 %cond, i32 %y, i32 0
@@ -928,8 +928,8 @@ define float @ldexp_flags_f32_mask_select_0(i1 %cond, float %x, i32 %y) {
 define float @ldexp_f32_mask_select_0_swap(i1 %cond, float %x, i32 %y) {
 ; CHECK-LABEL: define float @ldexp_f32_mask_select_0_swap
 ; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], i32 0, i32 [[Y]]
-; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[SELECT]])
+; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[Y]])
+; CHECK-NEXT:    [[LDEXP:%.*]] = select i1 [[COND]], float [[X]], float [[TMP1]]
 ; CHECK-NEXT:    ret float [[LDEXP]]
 ;
   %select = select i1 %cond, i32 0, i32 %y
@@ -992,8 +992,8 @@ define float @ldexp_f32_mask_select_0_strictfp(i1 %cond, float %x, i32 %y) #0 {
 define <2 x float> @ldexp_v2f32_mask_select_0(<2 x i1> %cond, <2 x float> %x, <2 x i32> %y) {
 ; CHECK-LABEL: define <2 x float> @ldexp_v2f32_mask_select_0
 ; CHECK-SAME: (<2 x i1> [[COND:%.*]], <2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
-; CHECK-NEXT:    [[SELECT:%.*]] = select <2 x i1> [[COND]], <2 x i32> [[Y]], <2 x i32> zeroinitializer
-; CHECK-NEXT:    [[LDEXP:%.*]] = call nnan nsz <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> [[SELECT]])
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> [[Y]])
+; CHECK-NEXT:    [[LDEXP:%.*]] = select <2 x i1> [[COND]], <2 x float> [[TMP1]], <2 x float> [[X]]
 ; CHECK-NEXT:    ret <2 x float> [[LDEXP]]
 ;
   %select = select <2 x i1> %cond, <2 x i32> %y, <2 x i32> zeroinitializer
@@ -1004,8 +1004,8 @@ define <2 x float> @ldexp_v2f32_mask_select_0(<2 x i1> %cond, <2 x float> %x, <2
 define <2 x float> @ldexp_v2f32_mask_select_0_swap(<2 x i1> %cond, <2 x float> %x, <2 x i32> %y) {
 ; CHECK-LABEL: define <2 x float> @ldexp_v2f32_mask_select_0_swap
 ; CHECK-SAME: (<2 x i1> [[COND:%.*]], <2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
-; CHECK-NEXT:    [[SELECT:%.*]] = select <2 x i1> [[COND]], <2 x i32> zeroinitializer, <2 x i32> [[Y]]
-; CHECK-NEXT:    [[LDEXP:%.*]] = call nnan nsz <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> [[SELECT]])
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> [[Y]])
+; CHECK-NEXT:    [[LDEXP:%.*]] = select <2 x i1> [[COND]], <2 x float> [[X]], <2 x float> [[TMP1]]
 ; CHECK-NEXT:    ret <2 x float> [[LDEXP]]
 ;
   %select = select <2 x i1> %cond, <2 x i32> zeroinitializer, <2 x i32> %y

>From 2fe6762138dae382f80dbe8f21d043c41f0e7ad2 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Tue, 2 Jul 2024 11:17:05 +0200
Subject: [PATCH 3/4] Add FMFSource to CreateLdexp

---
 llvm/include/llvm/IR/IRBuilder.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h
index d4b7f21b60a4b..31a1fef321995 100644
--- a/llvm/include/llvm/IR/IRBuilder.h
+++ b/llvm/include/llvm/IR/IRBuilder.h
@@ -1024,10 +1024,11 @@ class IRBuilderBase {
   }
 
   /// Create call to the ldexp intrinsic.
-  Value *CreateLdexp(Value *Src, Value *Exp, const Twine &Name = "") {
+  Value *CreateLdexp(Value *Src, Value *Exp, Instruction *FMFSource = nullptr,
+                     const Twine &Name = "") {
     assert(!IsFPConstrained && "TODO: Support strictfp");
     return CreateIntrinsic(Intrinsic::ldexp, {Src->getType(), Exp->getType()},
-                           {Src, Exp}, nullptr, Name);
+                           {Src, Exp}, FMFSource, Name);
   }
 
   /// Create a call to the arithmetic_fence intrinsic.

>From d7c42022d51bd176aefadd7e672413e22239c211 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Tue, 2 Jul 2024 13:26:21 +0200
Subject: [PATCH 4/4] Use copyFastMathFlags

---
 llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index b6642b8bd6a39..0ca56f08c333d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2661,7 +2661,7 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
 
       if (NewLdexp) {
         Select->takeName(II);
-        cast<Instruction>(NewLdexp)->copyIRFlags(II);
+        cast<Instruction>(NewLdexp)->copyFastMathFlags(II);
         return replaceInstUsesWith(*II, Select);
       }
     }



More information about the llvm-commits mailing list