From 47f5da47f527876d1c00a7c1d1deae9a1be07ef7 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Wed, 30 Nov 2022 15:31:55 -0500 Subject: [PATCH] [InstSimplify] (X && Y) ? X : Y --> Y Similar to the recent fold that was added for 'or' in D138815: https://alive2.llvm.org/ce/z/PBapTJ --- llvm/lib/Analysis/InstructionSimplify.cpp | 4 +++ .../test/Transforms/InstSimplify/select-logical.ll | 35 ++++++++-------------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 2190f20..77687ab 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -4555,6 +4555,10 @@ static Value *simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, if (match(TrueVal, m_One()) && match(FalseVal, m_ZeroInt())) return Cond; + // (X && Y) ? X : Y --> Y (commuted 2 ways) + if (match(Cond, m_c_LogicalAnd(m_Specific(TrueVal), m_Specific(FalseVal)))) + return FalseVal; + // (X || Y) ? X : Y --> X (commuted 2 ways) if (match(Cond, m_c_LogicalOr(m_Specific(TrueVal), m_Specific(FalseVal)))) return TrueVal; diff --git a/llvm/test/Transforms/InstSimplify/select-logical.ll b/llvm/test/Transforms/InstSimplify/select-logical.ll index 349a396..70e5a55 100644 --- a/llvm/test/Transforms/InstSimplify/select-logical.ll +++ b/llvm/test/Transforms/InstSimplify/select-logical.ll @@ -455,8 +455,8 @@ define <2 x i1> @select_or_same_op_vector2_poison(<2 x i1> %x, <2 x i1> %y) { ; negative test - must have common operands -define i1 @select_or_same_op_negatvie(i1 %x, i1 %y, i1 %z) { -; CHECK-LABEL: @select_or_same_op_negatvie( +define i1 @select_or_same_op_negative(i1 %x, i1 %y, i1 %z) { +; CHECK-LABEL: @select_or_same_op_negative( ; CHECK-NEXT: [[OR:%.*]] = or i1 [[X:%.*]], [[Y:%.*]] ; CHECK-NEXT: [[R:%.*]] = select i1 [[OR]], i1 [[X]], i1 [[Z:%.*]] ; CHECK-NEXT: ret i1 [[R]] @@ -470,9 +470,7 @@ define i1 @select_or_same_op_negatvie(i1 %x, i1 %y, i1 %z) { define i1 @select_and_same_op(i1 %x, i1 %y) { ; CHECK-LABEL: @select_and_same_op( -; CHECK-NEXT: [[A:%.*]] = and i1 [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[R:%.*]] = select i1 [[A]], i1 [[X]], i1 [[Y]] -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 [[Y:%.*]] ; %a = and i1 %x, %y %r = select i1 %a, i1 %x, i1 %y @@ -482,9 +480,7 @@ define i1 @select_and_same_op(i1 %x, i1 %y) { define i1 @select_and_same_op_commute(i1 %x, i1 %y) { ; CHECK-LABEL: @select_and_same_op_commute( -; CHECK-NEXT: [[A:%.*]] = and i1 [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[R:%.*]] = select i1 [[A]], i1 [[Y]], i1 [[X]] -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 [[X:%.*]] ; %a = and i1 %x, %y %r = select i1 %a, i1 %y, i1 %x @@ -494,9 +490,7 @@ define i1 @select_and_same_op_commute(i1 %x, i1 %y) { define <2 x i1> @select_and_same_op_vector1(<2 x i1> %x, <2 x i1> %y) { ; CHECK-LABEL: @select_and_same_op_vector1( -; CHECK-NEXT: [[A:%.*]] = and <2 x i1> [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[A]], <2 x i1> [[X]], <2 x i1> [[Y]] -; CHECK-NEXT: ret <2 x i1> [[R]] +; CHECK-NEXT: ret <2 x i1> [[Y:%.*]] ; %a = and <2 x i1> %x, %y %r = select <2 x i1> %a, <2 x i1> %x, <2 x i1> %y @@ -506,9 +500,7 @@ define <2 x i1> @select_and_same_op_vector1(<2 x i1> %x, <2 x i1> %y) { define i1 @select_logic_and1_same_op(i1 %x, i1 %y) { ; CHECK-LABEL: @select_logic_and1_same_op( -; CHECK-NEXT: [[A:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false -; CHECK-NEXT: [[R:%.*]] = select i1 [[A]], i1 [[X]], i1 [[Y]] -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 [[Y:%.*]] ; %a = select i1 %x, i1 %y, i1 false %r = select i1 %a, i1 %x, i1 %y @@ -518,9 +510,7 @@ define i1 @select_logic_and1_same_op(i1 %x, i1 %y) { define i1 @select_logic_and2_same_op(i1 %x, i1 %y) { ; CHECK-LABEL: @select_logic_and2_same_op( -; CHECK-NEXT: [[A:%.*]] = select i1 [[Y:%.*]], i1 [[X:%.*]], i1 false -; CHECK-NEXT: [[R:%.*]] = select i1 [[A]], i1 [[X]], i1 [[Y]] -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 [[Y:%.*]] ; %a = select i1 %y, i1 %x, i1 false %r = select i1 %a, i1 %x, i1 %y @@ -530,15 +520,14 @@ define i1 @select_logic_and2_same_op(i1 %x, i1 %y) { define <2 x i1> @select_and_same_op_vector2(<2 x i1> %x, <2 x i1> %y) { ; CHECK-LABEL: @select_and_same_op_vector2( -; CHECK-NEXT: [[A:%.*]] = select <2 x i1> [[X:%.*]], <2 x i1> [[Y:%.*]], <2 x i1> zeroinitializer -; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[A]], <2 x i1> [[X]], <2 x i1> [[Y]] -; CHECK-NEXT: ret <2 x i1> [[R]] +; CHECK-NEXT: ret <2 x i1> [[Y:%.*]] ; %a = select <2 x i1> %x, <2 x i1> %y, <2 x i1> zeroinitializer %r = select <2 x i1> %a, <2 x i1> %x, <2 x i1> %y ret <2 x i1> %r } +; TODO: this could transform to Y ; (X && Y) ? X : Y --> Y define <2 x i1> @select_and_same_op_vector2_poison(<2 x i1> %x, <2 x i1> %y) { @@ -552,8 +541,10 @@ define <2 x i1> @select_and_same_op_vector2_poison(<2 x i1> %x, <2 x i1> %y) { ret <2 x i1> %r } -define i1 @select_and_same_op_negatvie(i1 %x, i1 %y, i1 %z) { -; CHECK-LABEL: @select_and_same_op_negatvie( +; negative test - must have common operands + +define i1 @select_and_same_op_negative(i1 %x, i1 %y, i1 %z) { +; CHECK-LABEL: @select_and_same_op_negative( ; CHECK-NEXT: [[A:%.*]] = and i1 [[X:%.*]], [[Y:%.*]] ; CHECK-NEXT: [[R:%.*]] = select i1 [[A]], i1 [[X]], i1 [[Z:%.*]] ; CHECK-NEXT: ret i1 [[R]] -- 2.7.4