Skip to content

Commit 5a90168

Browse files
authored
[ValueTracking] Provide getUnderlyingObjectAggressive fallback (#123019)
This callsite assumes `getUnderlyingObjectAggressive` returns a non-null pointer: https://github.com/llvm/llvm-project/blob/273a94b3d5a78cd9122c7b3bbb5d5a87147735d2/llvm/lib/Transforms/IPO/FunctionAttrs.cpp#L124 But it can return null when there are cycles in the value chain so there is no more `Worklist` item anymore to explore, in which case it just returns `Object` at the end of the function without ever setting it: https://github.com/llvm/llvm-project/blob/9b5857a68381652dbea2a0c9efa734b6c4cf38c9/llvm/lib/Analysis/ValueTracking.cpp#L6866-L6867 https://github.com/llvm/llvm-project/blob/9b5857a68381652dbea2a0c9efa734b6c4cf38c9/llvm/lib/Analysis/ValueTracking.cpp#L6889 `getUnderlyingObject` does not seem to return null either judging by looking at its code and its callsites, so I think it is not likely to be the author's intention that `getUnderlyingObjectAggressive` returns null. So this checks whether `Object` is null at the end, and if so, falls back to the original first value. --- The test case here was reduced by bugpoint and further reduced manually, but I find it hard to reduce it further. To trigger this bug, the memory operation should not be reachable from the entry BB, because the `phi`s should form a cycle without introducing another value from the entry. I tried a minimal `phi` cycle with three BBs (entry BB + two BBs in a cycle), but it was skipped here: https://github.com/llvm/llvm-project/blob/273a94b3d5a78cd9122c7b3bbb5d5a87147735d2/llvm/lib/Transforms/IPO/FunctionAttrs.cpp#L121-L122 To get the result that's not `ModRefInfo::NoModRef`, the length of `phi` chain needed to be greater than the `MaxLookup` value set in this function: https://github.com/llvm/llvm-project/blob/02403f4e450b86d93197dd34045ff40a34b21494/llvm/lib/Analysis/BasicAliasAnalysis.cpp#L744 But just lengthening the `phi` chain to 8 didn't trigger the same error in `getUnderlyingObjectAggressive` because `getUnderlyingObject` here passes through a single-chain `phi`s so not all `phi`s end up in `Visited`: https://github.com/llvm/llvm-project/blob/9b5857a68381652dbea2a0c9efa734b6c4cf38c9/llvm/lib/Analysis/ValueTracking.cpp#L6863 So I just submit here the smallest test case I managed to create. --- Fixes #117308 and fixes #122166.
1 parent 6655c53 commit 5a90168

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6886,7 +6886,7 @@ const Value *llvm::getUnderlyingObjectAggressive(const Value *V) {
68866886
return FirstObject;
68876887
} while (!Worklist.empty());
68886888

6889-
return Object;
6889+
return Object ? Object : FirstObject;
68906890
}
68916891

68926892
/// This is the function that does the work of looking through basic
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
; RUN: opt -passes=function-attrs -S < %s
2+
3+
; Regression test for a null-returning bug of getUnderlyingObjectAggressive().
4+
; This should not crash.
5+
define void @phi_cycle() {
6+
bb:
7+
unreachable
8+
9+
bb1: ; preds = %bb17
10+
br label %bb2
11+
12+
bb2: ; preds = %bb5, %bb1
13+
%phi = phi ptr [ %phi6, %bb1 ], [ %phi6, %bb5 ]
14+
br i1 poison, label %bb4, label %bb3
15+
16+
bb3: ; preds = %bb2
17+
%getelementptr = getelementptr inbounds i8, ptr %phi, i32 poison
18+
br label %bb5
19+
20+
bb4: ; preds = %bb2
21+
br label %bb7
22+
23+
bb5: ; preds = %bb15, %bb3
24+
%phi6 = phi ptr [ %getelementptr, %bb3 ], [ %phi16, %bb15 ]
25+
br i1 poison, label %bb17, label %bb2
26+
27+
bb7: ; preds = %bb15, %bb4
28+
%phi8 = phi ptr [ %phi, %bb4 ], [ %phi16, %bb15 ]
29+
br i1 poison, label %bb11, label %bb9
30+
31+
bb9: ; preds = %bb7
32+
%getelementptr10 = getelementptr inbounds i8, ptr %phi8, i32 1
33+
store i8 poison, ptr %phi8, align 1
34+
br label %bb15
35+
36+
bb11: ; preds = %bb7
37+
br i1 poison, label %bb13, label %bb12
38+
39+
bb12: ; preds = %bb11
40+
br label %bb13
41+
42+
bb13: ; preds = %bb12, %bb11
43+
%getelementptr14 = getelementptr inbounds i8, ptr %phi8, i32 poison
44+
br label %bb15
45+
46+
bb15: ; preds = %bb13, %bb9
47+
%phi16 = phi ptr [ %getelementptr14, %bb13 ], [ %getelementptr10, %bb9 ]
48+
br i1 poison, label %bb5, label %bb7
49+
50+
bb17: ; preds = %bb5
51+
br label %bb1
52+
}

0 commit comments

Comments
 (0)