[llvm] 240acb0 - [InstCombine] avoid infinite loops with select folds of constant expressions

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sun Jun 20 06:53:14 PDT 2021


Author: Sanjay Patel
Date: 2021-06-20T09:46:25-04:00
New Revision: 240acb0cff3f7a5b33e29ad7df2081dd9140d630

URL: https://github.com/llvm/llvm-project/commit/240acb0cff3f7a5b33e29ad7df2081dd9140d630
DIFF: https://github.com/llvm/llvm-project/commit/240acb0cff3f7a5b33e29ad7df2081dd9140d630.diff

LOG: [InstCombine] avoid infinite loops with select folds of constant expressions

This pair of transforms was added recently with:
8591640379ac9175a

And could lead to conflicting folds:
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=35399

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
    llvm/test/Transforms/InstCombine/select-and-or.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 2308cdfe0e11..eadc826c7190 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -2709,13 +2709,15 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
     // DeMorgan in select form: !a && !b --> !(a || b)
     // select !a, !b, false --> not (select a, true, b)
     if (match(&SI, m_LogicalAnd(m_Not(m_Value(A)), m_Not(m_Value(B)))) &&
-        (CondVal->hasOneUse() || TrueVal->hasOneUse()))
+        (CondVal->hasOneUse() || TrueVal->hasOneUse()) &&
+        !match(A, m_ConstantExpr()) && !match(B, m_ConstantExpr()))
       return BinaryOperator::CreateNot(Builder.CreateSelect(A, One, B));
 
     // DeMorgan in select form: !a || !b --> !(a && b)
     // select !a, true, !b --> not (select a, b, false)
     if (match(&SI, m_LogicalOr(m_Not(m_Value(A)), m_Not(m_Value(B)))) &&
-        (CondVal->hasOneUse() || FalseVal->hasOneUse()))
+        (CondVal->hasOneUse() || FalseVal->hasOneUse()) &&
+        !match(A, m_ConstantExpr()) && !match(B, m_ConstantExpr()))
       return BinaryOperator::CreateNot(Builder.CreateSelect(A, B, Zero));
 
     // select (select a, true, b), true, b -> select a, true, b

diff  --git a/llvm/test/Transforms/InstCombine/select-and-or.ll b/llvm/test/Transforms/InstCombine/select-and-or.ll
index 5d6352e3484c..8cd473525aeb 100644
--- a/llvm/test/Transforms/InstCombine/select-and-or.ll
+++ b/llvm/test/Transforms/InstCombine/select-and-or.ll
@@ -420,3 +420,31 @@ define i1 @not_false_not_use3(i1 %x, i1 %y) {
   %r = select i1 %notx, i1 false, i1 %noty
   ret i1 %r
 }
+
+; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=35399
+
+ at g1 = external global i16
+ at g2 = external global i16
+
+define i1 @demorgan_select_infloop1(i1 %L) {
+; CHECK-LABEL: @demorgan_select_infloop1(
+; CHECK-NEXT:    [[NOT_L:%.*]] = xor i1 [[L:%.*]], true
+; CHECK-NEXT:    [[C15:%.*]] = select i1 [[NOT_L]], i1 xor (i1 and (i1 icmp eq (i16* getelementptr inbounds (i16, i16* @g2, i64 1), i16* @g1), i1 icmp ne (i16* getelementptr inbounds (i16, i16* @g2, i64 1), i16* @g1)), i1 true), i1 false
+; CHECK-NEXT:    ret i1 [[C15]]
+;
+  %not.L = xor i1 %L, true
+  %C15 = select i1 %not.L, i1 xor (i1 and (i1 icmp eq (i16* getelementptr inbounds (i16, i16* @g2, i64 1), i16* @g1), i1 icmp ne (i16* getelementptr inbounds (i16, i16* @g2, i64 1), i16* @g1)), i1 true), i1 false
+  ret i1 %C15
+}
+
+
+define i1 @demorgan_select_infloop2(i1 %L) {
+; CHECK-LABEL: @demorgan_select_infloop2(
+; CHECK-NEXT:    [[NOT_L:%.*]] = xor i1 [[L:%.*]], true
+; CHECK-NEXT:    [[C15:%.*]] = select i1 [[NOT_L]], i1 true, i1 xor (i1 and (i1 icmp eq (i16* getelementptr inbounds (i16, i16* @g2, i64 1), i16* @g1), i1 icmp ne (i16* getelementptr inbounds (i16, i16* @g2, i64 1), i16* @g1)), i1 true)
+; CHECK-NEXT:    ret i1 [[C15]]
+;
+  %not.L = xor i1 %L, true
+  %C15 = select i1 %not.L, i1 true, i1 xor (i1 and (i1 icmp eq (i16* getelementptr inbounds (i16, i16* @g2, i64 1), i16* @g1), i1 icmp ne (i16* getelementptr inbounds (i16, i16* @g2, i64 1), i16* @g1)), i1 true)
+  ret i1 %C15
+}


        


More information about the llvm-commits mailing list