Skip to content

[InstCombine] Fold select of undef to freeze #96773

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

nikic
Copy link
Contributor

@nikic nikic commented Jun 26, 2024

Fold select(c, undef, x) to freeze(x), in the case where we can't fold this to just x, because x is potentially poison (and does not imply c is poison).

Fold (select c, undef, x) to freeze(x), in the case where we can't
fold this to just x, because x is potentially poison (and does not
imply c is poison).
@llvmbot
Copy link
Member

llvmbot commented Jun 26, 2024

@llvm/pr-subscribers-llvm-transforms

Author: Nikita Popov (nikic)

Changes

Fold select(c, undef, x) to freeze(x), in the case where we can't fold this to just x, because x is potentially poison (and does not imply c is poison).


Full diff: https://github.com/llvm/llvm-project/pull/96773.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp (+9)
  • (modified) llvm/test/Transforms/InstCombine/select.ll (+4-4)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 27563d4414073..c457e719d3ba9 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -4016,5 +4016,14 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
   if (CondVal->getType() == SI.getType() && isKnownInversion(FalseVal, TrueVal))
     return BinaryOperator::CreateXor(CondVal, FalseVal);
 
+  // select Cond, undef, X -> freeze(X)
+  // select Cond, X, undef -> freeze(X)
+  // The case where X is non-poison (or implies the condition is poison) is
+  // already handled by InstSimplify.
+  if (isa<UndefValue>(TrueVal))
+    return new FreezeInst(FalseVal);
+  if (isa<UndefValue>(FalseVal))
+    return new FreezeInst(TrueVal);
+
   return nullptr;
 }
diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index b37e9175b26a5..9f150c6e57e20 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -2562,7 +2562,7 @@ exit:
 ; https://reviews.llvm.org/D83360
 define i32 @false_undef(i1 %cond, i32 %x) {
 ; CHECK-LABEL: @false_undef(
-; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND:%.*]], i32 [[X:%.*]], i32 undef
+; CHECK-NEXT:    [[S:%.*]] = freeze i32 [[X:%.*]]
 ; CHECK-NEXT:    ret i32 [[S]]
 ;
   %s = select i1 %cond, i32 %x, i32 undef
@@ -2571,7 +2571,7 @@ define i32 @false_undef(i1 %cond, i32 %x) {
 
 define i32 @true_undef(i1 %cond, i32 %x) {
 ; CHECK-LABEL: @true_undef(
-; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND:%.*]], i32 undef, i32 [[X:%.*]]
+; CHECK-NEXT:    [[S:%.*]] = freeze i32 [[X:%.*]]
 ; CHECK-NEXT:    ret i32 [[S]]
 ;
   %s = select i1 %cond, i32 undef, i32 %x
@@ -2580,7 +2580,7 @@ define i32 @true_undef(i1 %cond, i32 %x) {
 
 define <2 x i32> @false_undef_vec(i1 %cond, <2 x i32> %x) {
 ; CHECK-LABEL: @false_undef_vec(
-; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND:%.*]], <2 x i32> [[X:%.*]], <2 x i32> undef
+; CHECK-NEXT:    [[S:%.*]] = freeze <2 x i32> [[X:%.*]]
 ; CHECK-NEXT:    ret <2 x i32> [[S]]
 ;
   %s = select i1 %cond, <2 x i32> %x, <2 x i32> undef
@@ -2589,7 +2589,7 @@ define <2 x i32> @false_undef_vec(i1 %cond, <2 x i32> %x) {
 
 define <2 x i32> @true_undef_vec(i1 %cond, <2 x i32> %x) {
 ; CHECK-LABEL: @true_undef_vec(
-; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND:%.*]], <2 x i32> undef, <2 x i32> [[X:%.*]]
+; CHECK-NEXT:    [[S:%.*]] = freeze <2 x i32> [[X:%.*]]
 ; CHECK-NEXT:    ret <2 x i32> [[S]]
 ;
   %s = select i1 %cond, <2 x i32> undef, <2 x i32> %x

dtcxzyw added a commit to dtcxzyw/llvm-opt-benchmark that referenced this pull request Jun 26, 2024
@goldsteinn
Copy link
Contributor

goldsteinn commented Jun 26, 2024

InstSimplify instead? (edit: obv not...)

But looks fine assuming dtcxzyw's benchmarks look fine.

@dtcxzyw
Copy link
Member

dtcxzyw commented Jun 26, 2024

I cannot tell whether this patch has a positive net effect. Some freezes are not eliminated in the end :(

@nikic
Copy link
Contributor Author

nikic commented Jun 27, 2024

Maybe we should wait on the nopoison attribute first? Though this will take time as it needs an LLVM upgrade in Rust first...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants