Skip to content

Commit 95eb49a

Browse files
committed
[SCEV] Bail out on mixed int/pointer in SCEVWrapPredicate::implies.
Fixes a crash when trying to extend the pointer start value to a narrow integer type after b6c29fd.
1 parent a9df1f6 commit 95eb49a

File tree

2 files changed

+125
-2
lines changed

2 files changed

+125
-2
lines changed

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14978,6 +14978,11 @@ bool SCEVWrapPredicate::implies(const SCEVPredicate *N,
1497814978
Flags != SCEVWrapPredicate::IncrementNUSW)
1497914979
return false;
1498014980

14981+
const SCEV *Start = AR->getStart();
14982+
const SCEV *OpStart = Op->AR->getStart();
14983+
if (Start->getType()->isPointerTy() != OpStart->getType()->isPointerTy())
14984+
return false;
14985+
1498114986
const SCEV *Step = AR->getStepRecurrence(SE);
1498214987
const SCEV *OpStep = Op->AR->getStepRecurrence(SE);
1498314988
if (!SE.isKnownPositive(Step) || !SE.isKnownPositive(OpStep))
@@ -14990,8 +14995,6 @@ bool SCEVWrapPredicate::implies(const SCEVPredicate *N,
1499014995
OpStep = SE.getNoopOrZeroExtend(OpStep, WiderTy);
1499114996

1499214997
bool IsNUW = Flags == SCEVWrapPredicate::IncrementNUSW;
14993-
const SCEV *OpStart = Op->AR->getStart();
14994-
const SCEV *Start = AR->getStart();
1499514998
OpStart = IsNUW ? SE.getNoopOrZeroExtend(OpStart, WiderTy)
1499614999
: SE.getNoopOrSignExtend(OpStart, WiderTy);
1499715000
Start = IsNUW ? SE.getNoopOrZeroExtend(Start, WiderTy)
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -passes='print<access-info>' -disable-output %s 2>&1 | FileCheck %s
3+
4+
target datalayout = "p:16:16"
5+
6+
define void @int_and_pointer_predicate(ptr %v, i32 %N) {
7+
; CHECK-LABEL: 'int_and_pointer_predicate'
8+
; CHECK-NEXT: loop:
9+
; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
10+
; CHECK-NEXT: Unknown data dependence.
11+
; CHECK-NEXT: Dependences:
12+
; CHECK-NEXT: Unknown:
13+
; CHECK-NEXT: store i16 0, ptr %gep.iv.i16, align 1 ->
14+
; CHECK-NEXT: store i16 0, ptr %v, align 1
15+
; CHECK-EMPTY:
16+
; CHECK-NEXT: Run-time memory checks:
17+
; CHECK-NEXT: Grouped accesses:
18+
; CHECK-EMPTY:
19+
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
20+
; CHECK-NEXT: SCEV assumptions:
21+
; CHECK-NEXT: {0,+,1}<%loop> Added Flags: <nusw>
22+
; CHECK-NEXT: {%v,+,4}<%loop> Added Flags: <nusw>
23+
; CHECK-EMPTY:
24+
; CHECK-NEXT: Expressions re-written:
25+
;
26+
entry:
27+
br label %loop
28+
29+
loop:
30+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
31+
%iv.i16 = trunc i64 %iv to i16
32+
%gep.iv.i16 = getelementptr { i16, i16 }, ptr %v, i16 %iv.i16
33+
store i16 0, ptr %gep.iv.i16, align 1
34+
store i16 0, ptr %v, align 1
35+
%iv.next = add i64 %iv, 1
36+
%iv.i32 = trunc i64 %iv to i32
37+
%.not = icmp ult i32 %N, %iv.i32
38+
br i1 %.not, label %exit, label %loop
39+
40+
exit:
41+
ret void
42+
}
43+
44+
define void @int_and_multiple_pointer_predicates(ptr %v, ptr %w, i32 %N) {
45+
; CHECK-LABEL: 'int_and_multiple_pointer_predicates'
46+
; CHECK-NEXT: loop:
47+
; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
48+
; CHECK-NEXT: Unknown data dependence.
49+
; CHECK-NEXT: Dependences:
50+
; CHECK-NEXT: Unknown:
51+
; CHECK-NEXT: store i16 0, ptr %gep.v, align 1 ->
52+
; CHECK-NEXT: store i16 0, ptr %v, align 1
53+
; CHECK-EMPTY:
54+
; CHECK-NEXT: Unknown:
55+
; CHECK-NEXT: store i16 0, ptr %gep.w, align 1 ->
56+
; CHECK-NEXT: store i16 0, ptr %w, align 1
57+
; CHECK-EMPTY:
58+
; CHECK-NEXT: Run-time memory checks:
59+
; CHECK-NEXT: Check 0:
60+
; CHECK-NEXT: Comparing group ([[GRP1:0x[0-9a-f]+]]):
61+
; CHECK-NEXT: ptr %v
62+
; CHECK-NEXT: Against group ([[GRP2:0x[0-9a-f]+]]):
63+
; CHECK-NEXT: ptr %w
64+
; CHECK-NEXT: Check 1:
65+
; CHECK-NEXT: Comparing group ([[GRP1]]):
66+
; CHECK-NEXT: ptr %v
67+
; CHECK-NEXT: Against group ([[GRP3:0x[0-9a-f]+]]):
68+
; CHECK-NEXT: %gep.w = getelementptr { i16, i16 }, ptr %w, i16 %iv.i16
69+
; CHECK-NEXT: Check 2:
70+
; CHECK-NEXT: Comparing group ([[GRP4:0x[0-9a-f]+]]):
71+
; CHECK-NEXT: %gep.v = getelementptr { i16, i16 }, ptr %v, i16 %iv.i16
72+
; CHECK-NEXT: Against group ([[GRP2]]):
73+
; CHECK-NEXT: ptr %w
74+
; CHECK-NEXT: Check 3:
75+
; CHECK-NEXT: Comparing group ([[GRP4]]):
76+
; CHECK-NEXT: %gep.v = getelementptr { i16, i16 }, ptr %v, i16 %iv.i16
77+
; CHECK-NEXT: Against group ([[GRP3]]):
78+
; CHECK-NEXT: %gep.w = getelementptr { i16, i16 }, ptr %w, i16 %iv.i16
79+
; CHECK-NEXT: Grouped accesses:
80+
; CHECK-NEXT: Group [[GRP1]]:
81+
; CHECK-NEXT: (Low: %v High: (2 + %v))
82+
; CHECK-NEXT: Member: %v
83+
; CHECK-NEXT: Group [[GRP4]]:
84+
; CHECK-NEXT: (Low: %v High: (6 + (4 * (trunc i32 %N to i16)) + %v))
85+
; CHECK-NEXT: Member: {%v,+,4}<%loop>
86+
; CHECK-NEXT: Group [[GRP2]]:
87+
; CHECK-NEXT: (Low: %w High: (2 + %w))
88+
; CHECK-NEXT: Member: %w
89+
; CHECK-NEXT: Group [[GRP3]]:
90+
; CHECK-NEXT: (Low: %w High: (6 + (4 * (trunc i32 %N to i16)) + %w))
91+
; CHECK-NEXT: Member: {%w,+,4}<%loop>
92+
; CHECK-EMPTY:
93+
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
94+
; CHECK-NEXT: SCEV assumptions:
95+
; CHECK-NEXT: {0,+,1}<%loop> Added Flags: <nusw>
96+
; CHECK-NEXT: {%v,+,4}<%loop> Added Flags: <nusw>
97+
; CHECK-NEXT: {%w,+,4}<%loop> Added Flags: <nusw>
98+
; CHECK-EMPTY:
99+
; CHECK-NEXT: Expressions re-written:
100+
;
101+
entry:
102+
br label %loop
103+
104+
loop:
105+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
106+
%iv.i16 = trunc i64 %iv to i16
107+
%gep.v = getelementptr { i16, i16 }, ptr %v, i16 %iv.i16
108+
store i16 0, ptr %gep.v, align 1
109+
store i16 0, ptr %v, align 1
110+
%gep.w = getelementptr { i16, i16 }, ptr %w, i16 %iv.i16
111+
store i16 0, ptr %gep.w, align 1
112+
store i16 0, ptr %w, align 1
113+
%iv.next = add i64 %iv, 1
114+
%iv.i32 = trunc i64 %iv to i32
115+
%.not = icmp ult i32 %N, %iv.i32
116+
br i1 %.not, label %exit, label %loop
117+
118+
exit:
119+
ret void
120+
}

0 commit comments

Comments
 (0)