From 6c232db2ae933ad8f53cc39c8387fdceef7e8542 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Fri, 30 Dec 2022 08:47:51 -0500 Subject: [PATCH] [InstSimplify] fold selects where true/false arm is the same as condition We managed to fold related patterns in issue #59704, but we were missing these more basic folds: https://alive2.llvm.org/ce/z/y6d7SN --- llvm/lib/Analysis/InstructionSimplify.cpp | 17 +++++++++++++++++ llvm/test/Transforms/InstSimplify/select-logical.ll | 12 ++++-------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 78b493d..48abf50 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -4605,6 +4605,23 @@ static Value *simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, if (TrueVal == FalseVal) return TrueVal; + if (Cond == TrueVal) { + // select i1 X, i1 X, i1 false --> X (logical-and) + if (match(FalseVal, m_ZeroInt())) + return Cond; + // select i1 X, i1 X, i1 true --> true + if (match(FalseVal, m_One())) + return ConstantInt::getTrue(Cond->getType()); + } + if (Cond == FalseVal) { + // select i1 X, i1 true, i1 X --> X (logical-or) + if (match(TrueVal, m_One())) + return Cond; + // select i1 X, i1 false, i1 X --> false + if (match(TrueVal, m_ZeroInt())) + return ConstantInt::getFalse(Cond->getType()); + } + // If the true or false value is poison, we can fold to the other value. // If the true or false value is undef, we can fold to the other value as // long as the other value isn't poison. diff --git a/llvm/test/Transforms/InstSimplify/select-logical.ll b/llvm/test/Transforms/InstSimplify/select-logical.ll index 1d1ee58..09109eb 100644 --- a/llvm/test/Transforms/InstSimplify/select-logical.ll +++ b/llvm/test/Transforms/InstSimplify/select-logical.ll @@ -556,8 +556,7 @@ define i1 @select_and_same_op_negative(i1 %x, i1 %y, i1 %z) { define i1 @and_same_op(i1 %x) { ; CHECK-LABEL: @and_same_op( -; CHECK-NEXT: [[R:%.*]] = select i1 [[X:%.*]], i1 [[X]], i1 false -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 [[X:%.*]] ; %r = select i1 %x, i1 %x, i1 false ret i1 %r @@ -565,8 +564,7 @@ define i1 @and_same_op(i1 %x) { define <2 x i1> @or_same_op(<2 x i1> %x) { ; CHECK-LABEL: @or_same_op( -; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[X:%.*]], <2 x i1> , <2 x i1> [[X]] -; CHECK-NEXT: ret <2 x i1> [[R]] +; CHECK-NEXT: ret <2 x i1> [[X:%.*]] ; %r = select <2 x i1> %x, <2 x i1> , <2 x i1> %x ret <2 x i1> %r @@ -574,8 +572,7 @@ define <2 x i1> @or_same_op(<2 x i1> %x) { define <2 x i1> @always_true_same_op(<2 x i1> %x) { ; CHECK-LABEL: @always_true_same_op( -; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[X:%.*]], <2 x i1> [[X]], <2 x i1> -; CHECK-NEXT: ret <2 x i1> [[R]] +; CHECK-NEXT: ret <2 x i1> ; %r = select <2 x i1> %x, <2 x i1> %x, <2 x i1> ret <2 x i1> %r @@ -583,8 +580,7 @@ define <2 x i1> @always_true_same_op(<2 x i1> %x) { define i1 @always_false_same_op(i1 %x) { ; CHECK-LABEL: @always_false_same_op( -; CHECK-NEXT: [[R:%.*]] = select i1 [[X:%.*]], i1 false, i1 [[X]] -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 false ; %r = select i1 %x, i1 false, i1 %x ret i1 %r -- 2.7.4