[llvm] [SimplifyCFG] Improve FoldTwoEntryPHINode when one of phi values is undef (PR #69021)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 13 11:49:33 PDT 2023


https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/69021

When converting select-like branches into a select, we can just use one phi value instead of creating a select if it is guaranteed not to be poison and another phi value is undef. After converting to select, we will lose information from the dominator tree.

Alive2: https://alive2.llvm.org/ce/z/rheXK4

Fixes #67342.


>From 35df6d09ce355e2e4db5d00bcc08c7b3776923d7 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Sat, 14 Oct 2023 02:28:56 +0800
Subject: [PATCH 1/2] [SimplifyCFG] Add pre-commit tests for PR67342. NFC.

---
 llvm/test/Transforms/SimplifyCFG/pr67342.ll | 52 +++++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 llvm/test/Transforms/SimplifyCFG/pr67342.ll

diff --git a/llvm/test/Transforms/SimplifyCFG/pr67342.ll b/llvm/test/Transforms/SimplifyCFG/pr67342.ll
new file mode 100644
index 000000000000000..e278c626acf1738
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/pr67342.ll
@@ -0,0 +1,52 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
+; RUN: opt -S -passes=simplifycfg < %s | FileCheck %s
+
+; Tests from PR67342
+define i16 @test1(i32 %err) {
+; CHECK-LABEL: define i16 @test1(
+; CHECK-SAME: i32 [[ERR:%.*]]) {
+; CHECK-NEXT:  bb3:
+; CHECK-NEXT:    [[_3:%.*]] = icmp slt i32 [[ERR]], 0
+; CHECK-NEXT:    [[OK:%.*]] = trunc i32 [[ERR]] to i16
+; CHECK-NEXT:    [[R_SROA_3_0:%.*]] = select i1 [[_3]], i16 undef, i16 [[OK]]
+; CHECK-NEXT:    ret i16 [[R_SROA_3_0]]
+;
+  %_3 = icmp slt i32 %err, 0
+  br i1 %_3, label %bb1, label %bb2
+
+bb2:
+  %ok = trunc i32 %err to i16
+  br label %bb3
+
+bb1:
+  br label %bb3
+
+bb3:
+  %r.sroa.3.0 = phi i16 [ undef, %bb1 ], [ %ok, %bb2 ]
+  ret i16 %r.sroa.3.0
+}
+
+; commuted test
+define i16 @test2(i32 %err) {
+; CHECK-LABEL: define i16 @test2(
+; CHECK-SAME: i32 [[ERR:%.*]]) {
+; CHECK-NEXT:  bb3:
+; CHECK-NEXT:    [[_3:%.*]] = icmp slt i32 [[ERR]], 0
+; CHECK-NEXT:    [[OK:%.*]] = trunc i32 [[ERR]] to i16
+; CHECK-NEXT:    [[R_SROA_3_0:%.*]] = select i1 [[_3]], i16 [[OK]], i16 undef
+; CHECK-NEXT:    ret i16 [[R_SROA_3_0]]
+;
+  %_3 = icmp slt i32 %err, 0
+  br i1 %_3, label %bb1, label %bb2
+
+bb2:
+  br label %bb3
+
+bb1:
+  %ok = trunc i32 %err to i16
+  br label %bb3
+
+bb3:
+  %r.sroa.3.0 = phi i16 [ %ok, %bb1 ], [ undef, %bb2 ]
+  ret i16 %r.sroa.3.0
+}

>From e3aa1dcc937e11b5f073224cbfbcbc0c677bd928 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Sat, 14 Oct 2023 02:32:08 +0800
Subject: [PATCH 2/2] [SimplifyCFG] Improve FoldTwoEntryPHINode when one of phi
 values is undef

---
 llvm/lib/Transforms/Utils/SimplifyCFG.cpp   | 19 ++++++++++++++++---
 llvm/test/Transforms/SimplifyCFG/pr67342.ll |  6 ++----
 2 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 35fead111aa9666..bab5363e63a85eb 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -3543,9 +3543,22 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
     Value *TrueVal = PN->getIncomingValueForBlock(IfTrue);
     Value *FalseVal = PN->getIncomingValueForBlock(IfFalse);
 
-    Value *Sel = Builder.CreateSelect(IfCond, TrueVal, FalseVal, "", DomBI);
-    PN->replaceAllUsesWith(Sel);
-    Sel->takeName(PN);
+    Value *ReplaceVal = nullptr;
+    if (isa<UndefValue>(TrueVal) &&
+        isGuaranteedNotToBePoison(FalseVal, /*AC*/ nullptr,
+                                  IfFalse->getTerminator(),
+                                  DTU ? &DTU->getDomTree() : nullptr, 0)) {
+      ReplaceVal = FalseVal;
+    } else if (isa<UndefValue>(FalseVal) &&
+               isGuaranteedNotToBePoison(
+                   TrueVal, /*AC*/ nullptr, IfFalse->getTerminator(),
+                   DTU ? &DTU->getDomTree() : nullptr, 0)) {
+      ReplaceVal = TrueVal;
+    } else {
+      ReplaceVal = Builder.CreateSelect(IfCond, TrueVal, FalseVal, "", DomBI);
+      ReplaceVal->takeName(PN);
+    }
+    PN->replaceAllUsesWith(ReplaceVal);
     PN->eraseFromParent();
   }
 
diff --git a/llvm/test/Transforms/SimplifyCFG/pr67342.ll b/llvm/test/Transforms/SimplifyCFG/pr67342.ll
index e278c626acf1738..c2c9f460d8e5f9e 100644
--- a/llvm/test/Transforms/SimplifyCFG/pr67342.ll
+++ b/llvm/test/Transforms/SimplifyCFG/pr67342.ll
@@ -8,8 +8,7 @@ define i16 @test1(i32 %err) {
 ; CHECK-NEXT:  bb3:
 ; CHECK-NEXT:    [[_3:%.*]] = icmp slt i32 [[ERR]], 0
 ; CHECK-NEXT:    [[OK:%.*]] = trunc i32 [[ERR]] to i16
-; CHECK-NEXT:    [[R_SROA_3_0:%.*]] = select i1 [[_3]], i16 undef, i16 [[OK]]
-; CHECK-NEXT:    ret i16 [[R_SROA_3_0]]
+; CHECK-NEXT:    ret i16 [[OK]]
 ;
   %_3 = icmp slt i32 %err, 0
   br i1 %_3, label %bb1, label %bb2
@@ -33,8 +32,7 @@ define i16 @test2(i32 %err) {
 ; CHECK-NEXT:  bb3:
 ; CHECK-NEXT:    [[_3:%.*]] = icmp slt i32 [[ERR]], 0
 ; CHECK-NEXT:    [[OK:%.*]] = trunc i32 [[ERR]] to i16
-; CHECK-NEXT:    [[R_SROA_3_0:%.*]] = select i1 [[_3]], i16 [[OK]], i16 undef
-; CHECK-NEXT:    ret i16 [[R_SROA_3_0]]
+; CHECK-NEXT:    ret i16 [[OK]]
 ;
   %_3 = icmp slt i32 %err, 0
   br i1 %_3, label %bb1, label %bb2



More information about the llvm-commits mailing list