[llvm] e35a9ec - [InstCombine] isFreeToInvert(): constant expressions aren't free to invert (PR50370)

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Mon May 17 04:58:17 PDT 2021


Author: Roman Lebedev
Date: 2021-05-17T14:58:05+03:00
New Revision: e35a9ecf3df8f26ce50f8429cbaaf5a0e0212e86

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

LOG: [InstCombine] isFreeToInvert(): constant expressions aren't free to invert (PR50370)

This fixes https://bugs.llvm.org/show_bug.cgi?id=50370,
which reports a yet another endless combine loop,
this one regressed from 554b1bced325a8d860ad00bd59020d66d01c95f8,
which fixed yet another endless combine loop (PR50308)

This code had fallen into the very typical pitfall of forgetting
that constant expressions exist, and they aren't free to invert,
because the `not` won't be absorbed by the "constant",
but will remain a (constant) expression...

Added: 
    

Modified: 
    llvm/include/llvm/Transforms/InstCombine/InstCombiner.h
    llvm/test/Transforms/InstCombine/not-add.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h b/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h
index aae0694e4cabe..ba0d41f9b7489 100644
--- a/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h
+++ b/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h
@@ -249,8 +249,8 @@ class LLVM_LIBRARY_VISIBILITY InstCombiner {
     if (BinaryOperator *BO = dyn_cast<BinaryOperator>(V))
       if (BO->getOpcode() == Instruction::Add ||
           BO->getOpcode() == Instruction::Sub)
-        if (isa<Constant>(BO->getOperand(0)) ||
-            isa<Constant>(BO->getOperand(1)))
+        if (match(BO, PatternMatch::m_c_BinOp(PatternMatch::m_Value(),
+                                              PatternMatch::m_ImmConstant())))
           return WillInvertAllUses;
 
     // Selects with invertible operands are freely invertible

diff  --git a/llvm/test/Transforms/InstCombine/not-add.ll b/llvm/test/Transforms/InstCombine/not-add.ll
index d372e7603724b..5ece88dbef13c 100644
--- a/llvm/test/Transforms/InstCombine/not-add.ll
+++ b/llvm/test/Transforms/InstCombine/not-add.ll
@@ -165,3 +165,35 @@ cond.end:
   %sub = sub nsw i32 %v3, %cond
   ret i32 %sub
 }
+
+ at g = extern_weak global i32
+define void @pr50370(i32 %x) {
+; CHECK-LABEL: @pr50370(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], 1
+; CHECK-NEXT:    [[B15:%.*]] = srem i32 ashr (i32 65536, i32 or (i32 zext (i1 icmp eq (i32* @g, i32* null) to i32), i32 65537)), [[XOR]]
+; CHECK-NEXT:    [[B22:%.*]] = add nsw i32 [[B15]], sdiv (i32 or (i32 zext (i1 icmp eq (i32* @g, i32* null) to i32), i32 65537), i32 2147483647)
+; CHECK-NEXT:    [[B14:%.*]] = srem i32 ashr (i32 65536, i32 or (i32 zext (i1 icmp eq (i32* @g, i32* null) to i32), i32 65537)), [[B22]]
+; CHECK-NEXT:    [[B12:%.*]] = add nuw nsw i32 [[B15]], ashr (i32 65536, i32 or (i32 zext (i1 icmp eq (i32* @g, i32* null) to i32), i32 65537))
+; CHECK-NEXT:    [[B8:%.*]] = shl i32 sdiv (i32 or (i32 zext (i1 icmp eq (i32* @g, i32* null) to i32), i32 65537), i32 2147483647), [[B14]]
+; CHECK-NEXT:    [[B2:%.*]] = xor i32 [[B12]], [[B8]]
+; CHECK-NEXT:    [[B:%.*]] = xor i32 [[B2]], -1
+; CHECK-NEXT:    store i32 [[B]], i32* undef, align 4
+; CHECK-NEXT:    ret void
+;
+entry:
+  %xor = xor i32 %x, 1
+  %or4 = or i32 or (i32 zext (i1 icmp eq (i32* @g, i32* null) to i32), i32 1), 65536
+  %B6 = ashr i32 65536, %or4
+  %B15 = srem i32 %B6, %xor
+  %B20 = sdiv i32 %or4, 2147483647
+  %B22 = add i32 %B15, %B20
+  %B14 = srem i32 %B6, %B22
+  %B12 = add i32 %B15, %B6
+  %B8 = shl i32 %B20, %B14
+  %B2 = xor i32 %B12, %B8
+  %B3 = or i32 %B12, undef
+  %B = xor i32 %B2, %B3
+  store i32 %B, i32* undef, align 4
+  ret void
+}


        


More information about the llvm-commits mailing list