-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[InstCombine] Propagate poison pow[i], [us]add, [us]sub and [us]mul #146750
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-llvm-transforms Author: jjasmine (badumbatish) ChangesFixes #146560. As the issue is about folding with poison and with power operand like 0.0 and 1.0, I didn't add any optimization for folding pow(x, 0) (is it even allowed? I'm not sure) Full diff: https://github.com/llvm/llvm-project/pull/146750.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index cb1dae92faf92..c7cbd627117da 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -6673,7 +6673,13 @@ Value *llvm::simplifyBinaryIntrinsic(Intrinsic::ID IID, Type *ReturnType,
if (auto *C1 = dyn_cast<Constant>(Op1))
return simplifyRelativeLoad(C0, C1, Q.DL);
break;
+ case Intrinsic::pow:
+ if (isa<PoisonValue>(Op0) || isa<PoisonValue>(Op1))
+ return PoisonValue::get(ReturnType);
+ break;
case Intrinsic::powi:
+ if (isa<PoisonValue>(Op0) || isa<PoisonValue>(Op1))
+ return PoisonValue::get(ReturnType);
if (auto *Power = dyn_cast<ConstantInt>(Op1)) {
// powi(x, 0) -> 1.0
if (Power->isZero())
diff --git a/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll b/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
index e45aa3fd09ce0..1fd47af6946cb 100644
--- a/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
+++ b/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
@@ -33,7 +33,7 @@ define void @powi(double %V, ptr%P) {
define void @powi_i16(float %V, ptr%P) {
; CHECK-LABEL: @powi_i16(
; CHECK-NEXT: store volatile float 1.000000e+00, ptr [[P:%.*]], align 4
-; CHECK-NEXT: store volatile float [[V:%.*]], ptr [[P]], align 4
+; CHECK-NEXT: store volatile float [[D:%.*]], ptr [[P]], align 4
; CHECK-NEXT: ret void
;
%B = tail call float @llvm.powi.f32.i16(float %V, i16 0) nounwind
@@ -44,3 +44,33 @@ define void @powi_i16(float %V, ptr%P) {
ret void
}
+
+define void @pow_poison_i16(i16 %arg_int,float %arg_flt, ptr %P) {
+; CHECK-LABEL: @pow_poison_i16(
+; CHECK-NEXT: store volatile float poison, ptr [[P:%.*]], align 4
+; CHECK-NEXT: store volatile float poison, ptr [[P]], align 4
+; CHECK-NEXT: store volatile float poison, ptr [[P]], align 4
+; CHECK-NEXT: store volatile float poison, ptr [[P]], align 4
+; CHECK-NEXT: store volatile float poison, ptr [[P]], align 4
+; CHECK-NEXT: store volatile float poison, ptr [[P]], align 4
+; CHECK-NEXT: ret void
+;
+ %2 = tail call float @llvm.powi.f32.i16(float poison, i16 %arg_int) nounwind
+ store volatile float %2, ptr %P
+
+ %3 = tail call float @llvm.pow(float poison, float %arg_flt) nounwind
+ store volatile float %3, ptr %P
+
+ %4 = tail call float @llvm.powi.f32.i16(float %arg_flt, i16 poison) nounwind
+ store volatile float %4, ptr %P
+
+ %5 = tail call float @llvm.pow(float %arg_flt, float poison) nounwind
+ store volatile float %5, ptr %P
+
+ %6 = tail call float @llvm.powi.f32.i16(float poison, i16 poison) nounwind
+ store volatile float %6, ptr %P
+
+ %7 = tail call float @llvm.pow(float poison, float poison) nounwind
+ store volatile float %7, ptr %P
+ ret void
+}
|
@llvm/pr-subscribers-llvm-analysis Author: jjasmine (badumbatish) ChangesFixes #146560. As the issue is about folding with poison and with power operand like 0.0 and 1.0, I didn't add any optimization for folding pow(x, 0) (is it even allowed? I'm not sure) Full diff: https://github.com/llvm/llvm-project/pull/146750.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index cb1dae92faf92..c7cbd627117da 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -6673,7 +6673,13 @@ Value *llvm::simplifyBinaryIntrinsic(Intrinsic::ID IID, Type *ReturnType,
if (auto *C1 = dyn_cast<Constant>(Op1))
return simplifyRelativeLoad(C0, C1, Q.DL);
break;
+ case Intrinsic::pow:
+ if (isa<PoisonValue>(Op0) || isa<PoisonValue>(Op1))
+ return PoisonValue::get(ReturnType);
+ break;
case Intrinsic::powi:
+ if (isa<PoisonValue>(Op0) || isa<PoisonValue>(Op1))
+ return PoisonValue::get(ReturnType);
if (auto *Power = dyn_cast<ConstantInt>(Op1)) {
// powi(x, 0) -> 1.0
if (Power->isZero())
diff --git a/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll b/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
index e45aa3fd09ce0..1fd47af6946cb 100644
--- a/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
+++ b/llvm/test/Transforms/InstSimplify/fold-intrinsics.ll
@@ -33,7 +33,7 @@ define void @powi(double %V, ptr%P) {
define void @powi_i16(float %V, ptr%P) {
; CHECK-LABEL: @powi_i16(
; CHECK-NEXT: store volatile float 1.000000e+00, ptr [[P:%.*]], align 4
-; CHECK-NEXT: store volatile float [[V:%.*]], ptr [[P]], align 4
+; CHECK-NEXT: store volatile float [[D:%.*]], ptr [[P]], align 4
; CHECK-NEXT: ret void
;
%B = tail call float @llvm.powi.f32.i16(float %V, i16 0) nounwind
@@ -44,3 +44,33 @@ define void @powi_i16(float %V, ptr%P) {
ret void
}
+
+define void @pow_poison_i16(i16 %arg_int,float %arg_flt, ptr %P) {
+; CHECK-LABEL: @pow_poison_i16(
+; CHECK-NEXT: store volatile float poison, ptr [[P:%.*]], align 4
+; CHECK-NEXT: store volatile float poison, ptr [[P]], align 4
+; CHECK-NEXT: store volatile float poison, ptr [[P]], align 4
+; CHECK-NEXT: store volatile float poison, ptr [[P]], align 4
+; CHECK-NEXT: store volatile float poison, ptr [[P]], align 4
+; CHECK-NEXT: store volatile float poison, ptr [[P]], align 4
+; CHECK-NEXT: ret void
+;
+ %2 = tail call float @llvm.powi.f32.i16(float poison, i16 %arg_int) nounwind
+ store volatile float %2, ptr %P
+
+ %3 = tail call float @llvm.pow(float poison, float %arg_flt) nounwind
+ store volatile float %3, ptr %P
+
+ %4 = tail call float @llvm.powi.f32.i16(float %arg_flt, i16 poison) nounwind
+ store volatile float %4, ptr %P
+
+ %5 = tail call float @llvm.pow(float %arg_flt, float poison) nounwind
+ store volatile float %5, ptr %P
+
+ %6 = tail call float @llvm.powi.f32.i16(float poison, i16 poison) nounwind
+ store volatile float %6, ptr %P
+
+ %7 = tail call float @llvm.pow(float poison, float poison) nounwind
+ store volatile float %7, ptr %P
+ ret void
+}
|
will add vector type into test case |
Is it possible to handle this in ConstantFolding? That way IRBuilder etc. will automatically fold it to poison without the need to run InstSimplify, see: #141821 (review) |
on it |
@lukel97 ok i digged around and prototyped in the codebase a bit, and together with this comment
I think these are not in ConstantFolding at the moment. but in InstructionSimplify. I tried handling this in ConstantFolding but it was clunky with how the Operands array to be passed in is <Const*>, requiring both arguments to pow[i] to both be poison to be foldable. Tagging @dtcxzyw for some directions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I see what you mean about having a possibly non-constant arg. In that case I think having it in InstSimplify is fine.
LGTM but please wait for another reviewer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't want to add more of these one-off special cases which result in different poison-propagation support between ValueTracking, ConstantFolding and InstSimplify. I've put up #146878 to consolidate ValueTracking and ConstantFolding. We can then do the same for InstSimplify. And then this should just become a matter of adding extra intrinsics to the list.
407b63b
to
6fd04bf
Compare
rebased and refactored. waiting for your pr to be merged. |
Refactor support for pow[i] poison folding by rebasing on Nikic's changes and implement the changes in InstructionSimplify. Fix a few test case and added more Intrinsics to switch case in ValueTracking.
8fc29ae
to
d2244eb
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, I think there's a few fold to poison cases in simplifyBinaryIntrinsic
can probably be removed afterwards as an NFC
Fixes #146560 as well as propagate poison for [us]add, [us]sub and [us]mul