Skip to content

Commit 4f046bc

Browse files
committed
[PHITranslateAddr] Require dominance when searching for translated address (PR57025)
This is a fix for PR57025 and an alternative to D131776. The problem in the phi-translation-to-wrong-context.ll test case is that phi translation of %gep.j into if2 pick %gep.i as the result. While this instruction has the correct pointer address, it occurs in a context where %i != 0. As such, we get a NoAlias result for the store in if2, even though they do alias for %i == 0 (which is legal in the original context of the pointer). PHITranslateValue already has a MustDominate option, which can be used to restrict PHI translation results to values that dominate the translated-into block. However, this is more aggressive than what we need and would significantly regress GVN results. In particular, if we have a pointer value that does not require any translation, then it is fine to continue using that value in the predecessor, because the context is still correct for the original query. We only run into problems if PHITranslateSubExpr() picks a completely random instruction in a context that may have preconditions that do not hold. Fix this by always performing the dominance checks in PHITranslateSubExpr(), without enabling the more general MustDominate requirement. Fixes llvm#57025. This also fixes the test case for llvm#30999, but I'm not sure whether that's just the particular test case, or a general solution to the problem. Differential Revision: https://reviews.llvm.org/D132935
1 parent 8dd14c4 commit 4f046bc

File tree

4 files changed

+13
-24
lines changed

4 files changed

+13
-24
lines changed

llvm/lib/Analysis/PHITransAddr.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -317,8 +317,7 @@ bool PHITransAddr::PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB,
317317
assert(DT || !MustDominate);
318318
assert(Verify() && "Invalid PHITransAddr!");
319319
if (DT && DT->isReachableFromEntry(PredBB))
320-
Addr =
321-
PHITranslateSubExpr(Addr, CurBB, PredBB, MustDominate ? DT : nullptr);
320+
Addr = PHITranslateSubExpr(Addr, CurBB, PredBB, DT);
322321
else
323322
Addr = nullptr;
324323
assert(Verify() && "Invalid PHITransAddr!");

llvm/test/Transforms/GVN/condprop-memdep-invalidation.ll

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,18 @@ define i16 @test_PR31651(ptr %ub.16) {
3535
; CHECK-NEXT: call void @use(i16 [[L_3]])
3636
; CHECK-NEXT: br label [[LOOP_1_LATCH]]
3737
; CHECK: loop.1.latch:
38-
; CHECK-NEXT: [[L_42:%.*]] = phi i16 [ [[L_3]], [[ELSE_2]] ], [ [[L_2]], [[THEN_2]] ]
3938
; CHECK-NEXT: [[IV_1_NEXT]] = add i16 [[IV_1]], 1
4039
; CHECK-NEXT: [[CMP_3:%.*]] = icmp slt i16 [[IV_1_NEXT]], 2
4140
; CHECK-NEXT: br i1 [[CMP_3]], label [[LOOP_1_HEADER]], label [[LOOP_2:%.*]]
4241
; CHECK: loop.2:
43-
; CHECK-NEXT: [[L_4:%.*]] = phi i16 [ [[L_42]], [[LOOP_1_LATCH]] ], [ [[L_4_PRE:%.*]], [[LOOP_2_LOOP_2_CRIT_EDGE:%.*]] ]
44-
; CHECK-NEXT: [[IV_2:%.*]] = phi i16 [ 0, [[LOOP_1_LATCH]] ], [ [[IV_2_NEXT:%.*]], [[LOOP_2_LOOP_2_CRIT_EDGE]] ]
45-
; CHECK-NEXT: [[SUM:%.*]] = phi i16 [ 0, [[LOOP_1_LATCH]] ], [ [[SUM_NEXT:%.*]], [[LOOP_2_LOOP_2_CRIT_EDGE]] ]
42+
; CHECK-NEXT: [[IV_2:%.*]] = phi i16 [ 0, [[LOOP_1_LATCH]] ], [ [[IV_2_NEXT:%.*]], [[LOOP_2]] ]
43+
; CHECK-NEXT: [[SUM:%.*]] = phi i16 [ 0, [[LOOP_1_LATCH]] ], [ [[SUM_NEXT:%.*]], [[LOOP_2]] ]
4644
; CHECK-NEXT: [[GEP_5:%.*]] = getelementptr [4 x i16], ptr [[UB_16]], i16 1, i16 [[IV_2]]
45+
; CHECK-NEXT: [[L_4:%.*]] = load i16, ptr [[GEP_5]], align 2
4746
; CHECK-NEXT: [[SUM_NEXT]] = add i16 [[SUM]], [[L_4]]
4847
; CHECK-NEXT: [[IV_2_NEXT]] = add i16 [[IV_2]], 1
4948
; CHECK-NEXT: [[CMP_4:%.*]] = icmp slt i16 [[IV_2_NEXT]], 2
50-
; CHECK-NEXT: br i1 [[CMP_4]], label [[LOOP_2_LOOP_2_CRIT_EDGE]], label [[EXIT:%.*]]
51-
; CHECK: loop.2.loop.2_crit_edge:
52-
; CHECK-NEXT: [[GEP_5_PHI_TRANS_INSERT:%.*]] = getelementptr [4 x i16], ptr [[UB_16]], i16 1, i16 [[IV_2_NEXT]]
53-
; CHECK-NEXT: [[L_4_PRE]] = load i16, ptr [[GEP_5_PHI_TRANS_INSERT]], align 2
54-
; CHECK-NEXT: br label [[LOOP_2]]
49+
; CHECK-NEXT: br i1 [[CMP_4]], label [[LOOP_2]], label [[EXIT:%.*]]
5550
; CHECK: exit:
5651
; CHECK-NEXT: ret i16 [[SUM_NEXT]]
5752
;

llvm/test/Transforms/GVN/memdep-unknown-deadblocks.ll

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,6 @@
2626
; Expected semantic of the function is that verify() will be called three
2727
; times, with the values 7, 42 and 42.
2828

29-
; FIXME: The value passed to the verify function is loaded by
30-
; %value = load i16, ptr %arr.j, align 1
31-
; but currently GVN is replacing it with a faulty PHI in the
32-
; store.done block.
33-
3429
declare void @verify(i16)
3530

3631
define void @test(i16 %g) {
@@ -39,8 +34,7 @@ define void @test(i16 %g) {
3934
; CHECK-GVN-NEXT: [[ARR:%.*]] = alloca [4 x i16], align 1
4035
; CHECK-GVN-NEXT: br label [[FOR_BODY:%.*]]
4136
; CHECK-GVN: for.body:
42-
; CHECK-GVN-NEXT: [[VALUE2:%.*]] = phi i16 [ undef, [[ENTRY:%.*]] ], [ [[DEAD:%.*]], [[WHILE_END:%.*]] ]
43-
; CHECK-GVN-NEXT: [[I:%.*]] = phi i16 [ 0, [[ENTRY]] ], [ [[NEXT_I:%.*]], [[WHILE_END]] ]
37+
; CHECK-GVN-NEXT: [[I:%.*]] = phi i16 [ 0, [[ENTRY:%.*]] ], [ [[NEXT_I:%.*]], [[WHILE_END:%.*]] ]
4438
; CHECK-GVN-NEXT: [[CMP0:%.*]] = icmp eq i16 [[I]], 0
4539
; CHECK-GVN-NEXT: br i1 [[CMP0]], label [[STORE_IDX_0:%.*]], label [[STORE_IDX_I:%.*]]
4640
; CHECK-GVN: store.idx.0:
@@ -51,26 +45,25 @@ define void @test(i16 %g) {
5145
; CHECK-GVN-NEXT: store i16 42, ptr [[ARR_I]], align 1
5246
; CHECK-GVN-NEXT: br label [[STORE_DONE]]
5347
; CHECK-GVN: store.done:
54-
; CHECK-GVN-NEXT: [[VALUE:%.*]] = phi i16 [ 42, [[STORE_IDX_I]] ], [ [[VALUE2]], [[STORE_IDX_0]] ]
5548
; CHECK-GVN-NEXT: br label [[WHILE_BODY:%.*]]
5649
; CHECK-GVN: while.body:
5750
; CHECK-GVN-NEXT: br i1 false, label [[WHILE_BODY_WHILE_BODY_CRIT_EDGE:%.*]], label [[WHILE_END]]
5851
; CHECK-GVN: while.body.while.body_crit_edge:
5952
; CHECK-GVN-NEXT: br label [[WHILE_BODY]]
6053
; CHECK-GVN: while.end:
6154
; CHECK-GVN-NEXT: [[ARR_J:%.*]] = getelementptr [4 x i16], ptr [[ARR]], i16 0, i16 [[I]]
55+
; CHECK-GVN-NEXT: [[VALUE:%.*]] = load i16, ptr [[ARR_J]], align 1
6256
; CHECK-GVN-NEXT: tail call void @verify(i16 [[VALUE]])
6357
; CHECK-GVN-NEXT: [[NEXT_I]] = add i16 [[I]], 1
6458
; CHECK-GVN-NEXT: [[ARR_NEXT_I:%.*]] = getelementptr [4 x i16], ptr [[ARR]], i16 0, i16 [[NEXT_I]]
65-
; CHECK-GVN-NEXT: [[DEAD]] = load i16, ptr [[ARR_NEXT_I]], align 1
6659
; CHECK-GVN-NEXT: [[CMP4:%.*]] = icmp slt i16 [[NEXT_I]], 3
6760
; CHECK-GVN-NEXT: br i1 [[CMP4]], label [[FOR_BODY]], label [[FOR_END:%.*]]
6861
; CHECK-GVN: for.end:
6962
; CHECK-GVN-NEXT: ret void
7063
;
7164
; CHECK-GVN-O1-LABEL: @test(
7265
; CHECK-GVN-O1-NEXT: entry:
73-
; CHECK-GVN-O1-NEXT: tail call void @verify(i16 42)
66+
; CHECK-GVN-O1-NEXT: tail call void @verify(i16 7)
7467
; CHECK-GVN-O1-NEXT: tail call void @verify(i16 42)
7568
; CHECK-GVN-O1-NEXT: tail call void @verify(i16 42)
7669
; CHECK-GVN-O1-NEXT: ret void

llvm/test/Transforms/GVN/phi-translation-to-wrong-context.ll

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
22
; RUN: opt -S -gvn < %s | FileCheck %s
33

4-
; FIXME
54
; Phi translation of %gep.j cannot use %gep.i, which is located in a context
65
; where %i != 0, and would result in incorrect NoAlias results in a context
76
; where %i == 0 may hold.
@@ -15,14 +14,17 @@ define i32 @test(i64 %i, i1 %c1, i1 %c2) {
1514
; CHECK-NEXT: br i1 [[C2:%.*]], label [[IF2:%.*]], label [[ELSE2:%.*]]
1615
; CHECK: if2:
1716
; CHECK-NEXT: store i32 1, ptr [[PTR]], align 4
17+
; CHECK-NEXT: [[GEP_J_PHI_TRANS_INSERT:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[I:%.*]]
18+
; CHECK-NEXT: [[V_PRE:%.*]] = load i32, ptr [[GEP_J_PHI_TRANS_INSERT]], align 4
1819
; CHECK-NEXT: br label [[JOIN:%.*]]
1920
; CHECK: else2:
2021
; CHECK-NEXT: store i32 2, ptr [[PTR]], align 4
2122
; CHECK-NEXT: br label [[JOIN]]
2223
; CHECK: join:
23-
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[I:%.*]], [[IF2]] ], [ 0, [[ELSE2]] ]
24+
; CHECK-NEXT: [[V:%.*]] = phi i32 [ [[V_PRE]], [[IF2]] ], [ 2, [[ELSE2]] ]
25+
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[I]], [[IF2]] ], [ 0, [[ELSE2]] ]
2426
; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[J]]
25-
; CHECK-NEXT: ret i32 2
27+
; CHECK-NEXT: ret i32 [[V]]
2628
; CHECK: else:
2729
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[I]], 0
2830
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])

0 commit comments

Comments
 (0)