Skip to content

Commit 9399292

Browse files
LebedevRIfhahn
authored andcommitted
[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 554b1bc, 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... (cherry-picked from e35a9ec)
1 parent d74493d commit 9399292

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

llvm/include/llvm/Transforms/InstCombine/InstCombiner.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,8 @@ class LLVM_LIBRARY_VISIBILITY InstCombiner {
249249
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(V))
250250
if (BO->getOpcode() == Instruction::Add ||
251251
BO->getOpcode() == Instruction::Sub)
252-
if (isa<Constant>(BO->getOperand(0)) ||
253-
isa<Constant>(BO->getOperand(1)))
252+
if (match(BO, PatternMatch::m_c_BinOp(PatternMatch::m_Value(),
253+
PatternMatch::m_ImmConstant())))
254254
return WillInvertAllUses;
255255

256256
// Selects with invertible operands are freely invertible

llvm/test/Transforms/InstCombine/not-add.ll

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,3 +165,35 @@ cond.end:
165165
%sub = sub nsw i32 %v3, %cond
166166
ret i32 %sub
167167
}
168+
169+
@g = extern_weak global i32
170+
define void @pr50370(i32 %x) {
171+
; CHECK-LABEL: @pr50370(
172+
; CHECK-NEXT: entry:
173+
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], 1
174+
; CHECK-NEXT: [[B15:%.*]] = srem i32 ashr (i32 65536, i32 or (i32 zext (i1 icmp eq (i32* @g, i32* null) to i32), i32 65537)), [[XOR]]
175+
; CHECK-NEXT: [[B22:%.*]] = add i32 [[B15]], sdiv (i32 or (i32 zext (i1 icmp eq (i32* @g, i32* null) to i32), i32 65537), i32 2147483647)
176+
; CHECK-NEXT: [[B14:%.*]] = srem i32 ashr (i32 65536, i32 or (i32 zext (i1 icmp eq (i32* @g, i32* null) to i32), i32 65537)), [[B22]]
177+
; CHECK-NEXT: [[B12:%.*]] = add nuw i32 [[B15]], ashr (i32 65536, i32 or (i32 zext (i1 icmp eq (i32* @g, i32* null) to i32), i32 65537))
178+
; CHECK-NEXT: [[B8:%.*]] = shl i32 sdiv (i32 or (i32 zext (i1 icmp eq (i32* @g, i32* null) to i32), i32 65537), i32 2147483647), [[B14]]
179+
; CHECK-NEXT: [[B2:%.*]] = xor i32 [[B12]], [[B8]]
180+
; CHECK-NEXT: [[B:%.*]] = xor i32 [[B2]], -1
181+
; CHECK-NEXT: store i32 [[B]], i32* undef, align 4
182+
; CHECK-NEXT: ret void
183+
;
184+
entry:
185+
%xor = xor i32 %x, 1
186+
%or4 = or i32 or (i32 zext (i1 icmp eq (i32* @g, i32* null) to i32), i32 1), 65536
187+
%B6 = ashr i32 65536, %or4
188+
%B15 = srem i32 %B6, %xor
189+
%B20 = sdiv i32 %or4, 2147483647
190+
%B22 = add i32 %B15, %B20
191+
%B14 = srem i32 %B6, %B22
192+
%B12 = add i32 %B15, %B6
193+
%B8 = shl i32 %B20, %B14
194+
%B2 = xor i32 %B12, %B8
195+
%B3 = or i32 %B12, undef
196+
%B = xor i32 %B2, %B3
197+
store i32 %B, i32* undef, align 4
198+
ret void
199+
}

0 commit comments

Comments
 (0)