[llvm] 115d2f6 - [InstCombine] canonicalize branch with logical-and-not condition

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 31 12:53:13 PDT 2022


Author: Sanjay Patel
Date: 2022-10-31T15:51:45-04:00
New Revision: 115d2f69a515cd756fa51969f5dba433475c459c

URL: https://github.com/llvm/llvm-project/commit/115d2f69a515cd756fa51969f5dba433475c459c
DIFF: https://github.com/llvm/llvm-project/commit/115d2f69a515cd756fa51969f5dba433475c459c.diff

LOG: [InstCombine] canonicalize branch with logical-and-not condition

https://alive2.llvm.org/ce/z/EfHlWN

In the motivating case from issue #58313,
this allows forming a duplicate 'not' op
which then gets CSE'd and simplifyCFG'd
and combined into the expected 'xor'.

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
    llvm/test/Transforms/InstCombine/branch.ll
    llvm/test/Transforms/PhaseOrdering/simplifycfg-options.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index ebdd325335fdd..4459e16c224de 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -3180,13 +3180,22 @@ Instruction *InstCombinerImpl::visitBranchInst(BranchInst &BI) {
 
   // Change br (not X), label True, label False to: br X, label False, True
   Value *Cond = BI.getCondition();
-  Value *X = nullptr;
+  Value *X;
   if (match(Cond, m_Not(m_Value(X))) && !isa<Constant>(X)) {
     // Swap Destinations and condition...
     BI.swapSuccessors();
     return replaceOperand(BI, 0, X);
   }
 
+  // br (X && !Y), T, F --> br ((X && Y) || !X), F, T
+  Value *Y;
+  if (isa<SelectInst>(Cond) &&
+      match(Cond, m_OneUse(m_LogicalAnd(m_Value(X), m_Not(m_Value(Y)))))) {
+    Value *AndOr = Builder.CreateSelect(X, Y, Builder.getTrue());
+    BI.swapSuccessors();
+    return replaceOperand(BI, 0, AndOr);
+  }
+
   // If the condition is irrelevant, remove the use so that other
   // transforms on the condition become more effective.
   if (!isa<ConstantInt>(Cond) && BI.getSuccessor(0) == BI.getSuccessor(1))

diff  --git a/llvm/test/Transforms/InstCombine/branch.ll b/llvm/test/Transforms/InstCombine/branch.ll
index 9636bd51ecc0d..f90c8a2512072 100644
--- a/llvm/test/Transforms/InstCombine/branch.ll
+++ b/llvm/test/Transforms/InstCombine/branch.ll
@@ -113,14 +113,14 @@ merge.2:
   ret i1 %merge.cond.2
 }
 
-; if (x && !y) ret 42; ret 3
+; if (x && !y) ret 42; ret 3 --> if (!x || y) ret 3; ret 42
 
 define i32 @logical_and_not(i1 %x, i1 %y) {
 ; CHECK-LABEL: @logical_and_not(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[NOTY:%.*]] = xor i1 [[Y:%.*]], true
-; CHECK-NEXT:    [[AND:%.*]] = select i1 [[X:%.*]], i1 [[NOTY]], i1 false
-; CHECK-NEXT:    br i1 [[AND]], label [[T:%.*]], label [[F:%.*]]
+; CHECK-NEXT:    [[NOT_X:%.*]] = xor i1 [[X:%.*]], true
+; CHECK-NEXT:    [[TMP0:%.*]] = select i1 [[NOT_X]], i1 true, i1 [[Y:%.*]]
+; CHECK-NEXT:    br i1 [[TMP0]], label [[F:%.*]], label [[T:%.*]]
 ; CHECK:       t:
 ; CHECK-NEXT:    ret i32 42
 ; CHECK:       f:
@@ -138,7 +138,7 @@ f:
   ret i32 3
 }
 
-; if (x && y || !x) ret 3; ret 42
+; if (x && y || !x) ret 3; ret 42 --> if (!x || y) ret 3; ret 42
 
 define i32 @logical_and_or(i1 %x, i1 %y) {
 ; CHECK-LABEL: @logical_and_or(

diff  --git a/llvm/test/Transforms/PhaseOrdering/simplifycfg-options.ll b/llvm/test/Transforms/PhaseOrdering/simplifycfg-options.ll
index bc1177f1a704c..062b343c3717e 100644
--- a/llvm/test/Transforms/PhaseOrdering/simplifycfg-options.ll
+++ b/llvm/test/Transforms/PhaseOrdering/simplifycfg-options.ll
@@ -105,16 +105,8 @@ end:
 define i1 @PR58313(i1 %lhs, i1 %rhs) {
 ; CHECK-LABEL: @PR58313(
 ; CHECK-NEXT:  andandend:
-; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[RHS:%.*]], true
-; CHECK-NEXT:    [[ANDANDVAL:%.*]] = select i1 [[LHS:%.*]], i1 [[TMP0]], i1 false
-; CHECK-NEXT:    br i1 [[ANDANDVAL]], label [[OROREND:%.*]], label [[OROR:%.*]]
-; CHECK:       oror:
-; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[LHS]], true
-; CHECK-NEXT:    [[ANDANDVAL3:%.*]] = select i1 [[TMP1]], i1 [[RHS]], i1 false
-; CHECK-NEXT:    br label [[OROREND]]
-; CHECK:       ororend:
-; CHECK-NEXT:    [[ORORVAL:%.*]] = phi i1 [ true, [[ANDANDEND:%.*]] ], [ [[ANDANDVAL3]], [[OROR]] ]
-; CHECK-NEXT:    ret i1 [[ORORVAL]]
+; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = xor i1 [[LHS:%.*]], [[RHS:%.*]]
+; CHECK-NEXT:    ret i1 [[SPEC_SELECT]]
 ;
 andandend:
   %0 = xor i1 %rhs, true


        


More information about the llvm-commits mailing list