1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 02:33:06 +01:00

[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...
This commit is contained in:
Roman Lebedev 2021-05-17 14:53:53 +03:00
parent e099d7d19d
commit faba1577fb
2 changed files with 34 additions and 2 deletions

View File

@ -249,8 +249,8 @@ public:
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

View File

@ -165,3 +165,35 @@ cond.end:
%sub = sub nsw i32 %v3, %cond
ret i32 %sub
}
@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
}