Skip to content

Commit 670c92a

Browse files
committed
[CodeGen] Remove redundent instructions generated by combineAddrModes.
CodeGenPare may optimize memory access modes. During such optimization, it might create a new instruction representing combined value. Later, If the optimization failed, the generated value is not removed and remains a dead instruction. Normally this won't be a problem as dead code will be eliminated later. However, in this case (Issue 58538), the generated instruction may trigger an infinite loop. The infinite loop involves `sinkCmpExpression`, where it tries to optimize the placeholder generated by us. (See the test case detailed in the issue) To fix this, we remove the unnecessary placeholder immediately when we abort the optimization. `AddressingModeCombiner` will keep track of the placeholder, and remove it if it is an inserted placeholder and has no uses. This patch fixes #58538, a test is also included. Reviewed By: skatkov Differential Revision: https://reviews.llvm.org/D147041
1 parent 8c124e3 commit 670c92a

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

llvm/lib/CodeGen/CodeGenPrepare.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3559,10 +3559,15 @@ class AddressingModeCombiner {
35593559
/// Original Address.
35603560
Value *Original;
35613561

3562+
/// Common value among addresses
3563+
Value *CommonValue = nullptr;
3564+
35623565
public:
35633566
AddressingModeCombiner(const SimplifyQuery &_SQ, Value *OriginalValue)
35643567
: SQ(_SQ), Original(OriginalValue) {}
35653568

3569+
~AddressingModeCombiner() { eraseCommonValueIfDead(); }
3570+
35663571
/// Get the combined AddrMode
35673572
const ExtAddrMode &getAddrMode() const { return AddrModes[0]; }
35683573

@@ -3647,13 +3652,21 @@ class AddressingModeCombiner {
36473652
if (!initializeMap(Map))
36483653
return false;
36493654

3650-
Value *CommonValue = findCommon(Map);
3655+
CommonValue = findCommon(Map);
36513656
if (CommonValue)
36523657
AddrModes[0].SetCombinedField(DifferentField, CommonValue, AddrModes);
36533658
return CommonValue != nullptr;
36543659
}
36553660

36563661
private:
3662+
/// `CommonValue` may be a placeholder inserted by us.
3663+
/// If the placeholder is not used, we should remove this dead instruction.
3664+
void eraseCommonValueIfDead() {
3665+
if (CommonValue && CommonValue->getNumUses() == 0)
3666+
if (Instruction *CommonInst = dyn_cast<Instruction>(CommonValue))
3667+
CommonInst->eraseFromParent();
3668+
}
3669+
36573670
/// Initialize Map with anchor values. For address seen
36583671
/// we set the value of different field saw in this address.
36593672
/// At the same time we find a common type for different field we will

llvm/test/CodeGen/X86/pr58538.ll

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
; RUN: opt -codegenprepare -mtriple=x86_64 %s -S -o - | FileCheck %s
2+
; RUN: opt -codegenprepare -mtriple=i386 %s -S -o - | FileCheck %s
3+
4+
define i32 @f(i32 %0) {
5+
; CHECK-LABEL: @f
6+
; CHECK: BB:
7+
; CHECK: %P0 = alloca i32, i32 8, align 4
8+
; CHECK: %P1 = getelementptr i32, ptr %P0, i32 1
9+
; CHECK: %1 = icmp eq i32 %0, 0
10+
; CHECK: %P2 = getelementptr i1, ptr %P1, i1 %1
11+
; CHECK: %2 = icmp eq i32 %0, 0
12+
; CHECK: %P3 = select i1 %2, ptr %P1, ptr %P2
13+
; CHECK: %L1 = load i32, ptr %P3, align 4
14+
; CHECK: ret i32 %L1
15+
BB:
16+
%P0 = alloca i32, i32 8
17+
%P1 = getelementptr i32, ptr %P0, i32 1
18+
%B0 = icmp eq i32 %0, 0
19+
br label %BB1
20+
21+
BB1: ; preds = %BB1, %BB
22+
%P2 = getelementptr i1, ptr %P1, i1 %B0
23+
br i1 false, label %BB1, label %BB2
24+
25+
BB2: ; preds = %BB1
26+
%P3 = select i1 %B0, ptr %P1, ptr %P2
27+
%L1 = load i32, ptr %P3
28+
ret i32 %L1
29+
}

0 commit comments

Comments
 (0)