Skip to content

Commit ac407a7

Browse files
committed
[SCEV][LSR] Prevent using undefined value in binops
On some occasions ReuseOrCreateCast may convert previously expanded value to undefined. That value may be passed by SCEVExpander as an argument to InsertBinop making IV chain undefined. Differential revision: https://reviews.llvm.org/D63928 llvm-svn: 365009
1 parent f826728 commit ac407a7

File tree

3 files changed

+262
-9
lines changed

3 files changed

+262
-9
lines changed

llvm/lib/Analysis/ScalarEvolutionExpander.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,10 @@ Value *SCEVExpander::ReuseOrCreateCast(Value *V, Type *Ty,
6060
// instructions that might be inserted before BIP.
6161
if (BasicBlock::iterator(CI) != IP || BIP == IP) {
6262
// Create a new cast, and leave the old cast in place in case
63-
// it is being used as an insert point. Clear its operand
64-
// so that it doesn't hold anything live.
63+
// it is being used as an insert point.
6564
Ret = CastInst::Create(Op, V, Ty, "", &*IP);
6665
Ret->takeName(CI);
6766
CI->replaceAllUsesWith(Ret);
68-
CI->setOperand(0, UndefValue::get(V->getType()));
6967
break;
7068
}
7169
Ret = CI;
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
; REQUIRES: arm-registered-target
2+
; RUN: opt -S -loop-reduce %s -o - | FileCheck %s
3+
4+
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
5+
target triple = "armv8-unknown-hurd-eabihf"
6+
7+
%"class.std::__1::vector.182" = type { %"class.std::__1::__vector_base.183" }
8+
%"class.std::__1::__vector_base.183" = type { i8*, i8*, %"class.std::__1::__compressed_pair.184" }
9+
%"class.std::__1::__compressed_pair.184" = type { %"struct.std::__1::__compressed_pair_elem.185" }
10+
%"struct.std::__1::__compressed_pair_elem.185" = type { i8* }
11+
%"class.std::__1::__vector_base_common" = type { i8 }
12+
13+
$vector_insert = comdat any
14+
15+
declare i8* @Allocate(i32) local_unnamed_addr
16+
declare void @Free(i8*) local_unnamed_addr
17+
declare void @_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv(%"class.std::__1::__vector_base_common"*) local_unnamed_addr
18+
declare i8* @memmove(i8*, i8*, i32) local_unnamed_addr
19+
20+
; Function Attrs: noimplicitfloat nounwind uwtable
21+
define linkonce_odr i32 @vector_insert(%"class.std::__1::vector.182"*, [1 x i32], i8*, i8*) local_unnamed_addr #1 comdat align 2 {
22+
; CHECK-LABEL: vector_insert
23+
%5 = extractvalue [1 x i32] %1, 0
24+
%6 = getelementptr inbounds %"class.std::__1::vector.182", %"class.std::__1::vector.182"* %0, i32 0, i32 0, i32 0
25+
%7 = load i8*, i8** %6, align 4
26+
; CHECK: [[LOAD:%[0-9]+]] = load i8*, i8**
27+
%8 = bitcast %"class.std::__1::vector.182"* %0 to i32*
28+
%9 = ptrtoint i8* %7 to i32
29+
; CHECK: [[NEW_CAST:%[0-9]+]] = ptrtoint i8* [[LOAD]] to i32
30+
; CHECK: [[OLD_CAST:%[0-9]+]] = ptrtoint i8* [[LOAD]] to i32
31+
%10 = sub i32 %5, %9
32+
%11 = getelementptr inbounds i8, i8* %7, i32 %10
33+
%12 = ptrtoint i8* %3 to i32
34+
%13 = ptrtoint i8* %2 to i32
35+
%14 = sub i32 %12, %13
36+
%15 = icmp sgt i32 %14, 0
37+
br i1 %15, label %18, label %16
38+
39+
; <label>:16: ; preds = %4
40+
%17 = ptrtoint i8* %11 to i32
41+
br label %148
42+
43+
; <label>:18: ; preds = %4
44+
%19 = getelementptr inbounds %"class.std::__1::vector.182", %"class.std::__1::vector.182"* %0, i32 0, i32 0, i32 2, i32 0, i32 0
45+
%20 = bitcast i8** %19 to i32*
46+
%21 = load i32, i32* %20, align 4
47+
%22 = getelementptr inbounds %"class.std::__1::vector.182", %"class.std::__1::vector.182"* %0, i32 0, i32 0, i32 1
48+
%23 = load i8*, i8** %22, align 4
49+
%24 = ptrtoint i8* %23 to i32
50+
%25 = sub i32 %21, %24
51+
%26 = icmp sgt i32 %14, %25
52+
%27 = bitcast i8** %22 to i32*
53+
br i1 %26, label %77, label %28
54+
55+
; <label>:28: ; preds = %18
56+
%29 = ptrtoint i8* %11 to i32
57+
%30 = sub i32 %24, %29
58+
%31 = icmp sgt i32 %14, %30
59+
br i1 %31, label %32, label %48
60+
61+
; <label>:32: ; preds = %28
62+
%33 = getelementptr inbounds i8, i8* %2, i32 %30
63+
%34 = icmp eq i8* %33, %3
64+
br i1 %34, label %43, label %35
65+
66+
; <label>:35: ; preds = %32, %35
67+
%36 = phi i8* [ %41, %35 ], [ %23, %32 ]
68+
%37 = phi i8* [ %39, %35 ], [ %33, %32 ]
69+
%38 = load i8, i8* %37, align 1
70+
store i8 %38, i8* %36, align 1
71+
%39 = getelementptr inbounds i8, i8* %37, i32 1
72+
%40 = load i8*, i8** %22, align 4
73+
%41 = getelementptr inbounds i8, i8* %40, i32 1
74+
store i8* %41, i8** %22, align 4
75+
%42 = icmp eq i8* %39, %3
76+
br i1 %42, label %43, label %35
77+
78+
; <label>:43: ; preds = %35, %32
79+
%44 = phi i8* [ %23, %32 ], [ %41, %35 ]
80+
%45 = icmp sgt i32 %30, 0
81+
br i1 %45, label %46, label %148
82+
83+
; <label>:46: ; preds = %43
84+
%47 = ptrtoint i8* %44 to i32
85+
br label %48
86+
87+
; <label>:48: ; preds = %46, %28
88+
%49 = phi i32 [ %47, %46 ], [ %24, %28 ]
89+
%50 = phi i8* [ %44, %46 ], [ %23, %28 ]
90+
%51 = phi i8* [ %33, %46 ], [ %3, %28 ]
91+
%52 = getelementptr inbounds i8, i8* %11, i32 %14
92+
%53 = ptrtoint i8* %52 to i32
93+
%54 = sub i32 %49, %53
94+
%55 = getelementptr inbounds i8, i8* %11, i32 %54
95+
%56 = icmp ult i8* %55, %23
96+
br i1 %56, label %63, label %57
97+
98+
; <label>:57: ; preds = %63, %48
99+
%58 = icmp eq i32 %54, 0
100+
br i1 %58, label %71, label %59
101+
102+
; <label>:59: ; preds = %57
103+
%60 = sub i32 0, %54
104+
%61 = getelementptr inbounds i8, i8* %50, i32 %60
105+
%62 = tail call i8* @memmove(i8* %61, i8* %11, i32 %54) #13
106+
br label %71
107+
108+
; <label>:63: ; preds = %48, %63
109+
%64 = phi i8* [ %69, %63 ], [ %50, %48 ]
110+
%65 = phi i8* [ %67, %63 ], [ %55, %48 ]
111+
%66 = load i8, i8* %65, align 1
112+
store i8 %66, i8* %64, align 1
113+
%67 = getelementptr inbounds i8, i8* %65, i32 1
114+
%68 = load i8*, i8** %22, align 4
115+
%69 = getelementptr inbounds i8, i8* %68, i32 1
116+
store i8* %69, i8** %22, align 4
117+
%70 = icmp eq i8* %67, %23
118+
br i1 %70, label %57, label %63
119+
120+
; <label>:71: ; preds = %57, %59
121+
%72 = ptrtoint i8* %51 to i32
122+
%73 = sub i32 %72, %13
123+
%74 = icmp eq i32 %73, 0
124+
br i1 %74, label %148, label %75
125+
126+
; <label>:75: ; preds = %71
127+
%76 = tail call i8* @memmove(i8* %11, i8* %2, i32 %73) #13
128+
br label %148
129+
130+
; <label>:77: ; preds = %18
131+
%78 = sub i32 %24, %9
132+
%79 = add i32 %78, %14
133+
%80 = icmp slt i32 %79, 0
134+
br i1 %80, label %81, label %83
135+
136+
; <label>:81: ; preds = %77
137+
%82 = bitcast %"class.std::__1::vector.182"* %0 to %"class.std::__1::__vector_base_common"*
138+
tail call void @_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv(%"class.std::__1::__vector_base_common"* %82) #15
139+
unreachable
140+
141+
; <label>:83: ; preds = %77
142+
%84 = sub i32 %21, %9
143+
%85 = icmp ult i32 %84, 1073741823
144+
br i1 %85, label %86, label %91
145+
146+
; <label>:86: ; preds = %83
147+
%87 = shl i32 %84, 1
148+
%88 = icmp ult i32 %87, %79
149+
%89 = select i1 %88, i32 %79, i32 %87
150+
%90 = icmp eq i32 %89, 0
151+
br i1 %90, label %94, label %91
152+
153+
; <label>:91: ; preds = %83, %86
154+
%92 = phi i32 [ %89, %86 ], [ 2147483647, %83 ]
155+
%93 = tail call i8* @Allocate(i32 %92) #13
156+
br label %94
157+
158+
; <label>:94: ; preds = %86, %91
159+
%95 = phi i32 [ %92, %91 ], [ 0, %86 ]
160+
%96 = phi i8* [ %93, %91 ], [ null, %86 ]
161+
%97 = getelementptr inbounds i8, i8* %96, i32 %10
162+
%98 = ptrtoint i8* %97 to i32
163+
%99 = getelementptr inbounds i8, i8* %96, i32 %95
164+
%100 = ptrtoint i8* %99 to i32
165+
%101 = icmp eq i8* %2, %3
166+
br i1 %101, label %111, label %102
167+
168+
; <label>:102: ; preds = %94, %102
169+
%103 = phi i8* [ %106, %102 ], [ %97, %94 ]
170+
%104 = phi i8* [ %107, %102 ], [ %2, %94 ]
171+
%105 = load i8, i8* %104, align 1
172+
store i8 %105, i8* %103, align 1
173+
%106 = getelementptr inbounds i8, i8* %103, i32 1
174+
%107 = getelementptr inbounds i8, i8* %104, i32 1
175+
%108 = icmp eq i8* %107, %3
176+
br i1 %108, label %109, label %102
177+
178+
; <label>:109: ; preds = %102
179+
%110 = ptrtoint i8* %106 to i32
180+
br label %111
181+
182+
; <label>:111: ; preds = %109, %94
183+
%112 = phi i32 [ %98, %94 ], [ %110, %109 ]
184+
%113 = load i8*, i8** %6, align 4
185+
%114 = icmp eq i8* %113, %11
186+
br i1 %114, label %124, label %115
187+
188+
; CHECK-LABEL: .preheader:
189+
; CHECK-NEXT: sub i32 [[OLD_CAST]], [[NEW_CAST]]
190+
; <label>:115: ; preds = %111, %115
191+
%116 = phi i8* [ %118, %115 ], [ %97, %111 ]
192+
%117 = phi i8* [ %119, %115 ], [ %11, %111 ]
193+
%118 = getelementptr inbounds i8, i8* %116, i32 -1
194+
%119 = getelementptr inbounds i8, i8* %117, i32 -1
195+
%120 = load i8, i8* %119, align 1
196+
store i8 %120, i8* %118, align 1
197+
%121 = icmp eq i8* %119, %113
198+
br i1 %121, label %122, label %115
199+
200+
; <label>:122: ; preds = %115
201+
%123 = ptrtoint i8* %118 to i32
202+
br label %124
203+
204+
; <label>:124: ; preds = %122, %111
205+
%125 = phi i32 [ %98, %111 ], [ %123, %122 ]
206+
%126 = phi i8* [ %97, %111 ], [ %118, %122 ]
207+
%127 = load i8*, i8** %22, align 4
208+
%128 = icmp eq i8* %127, %11
209+
br i1 %128, label %129, label %131
210+
211+
; <label>:129: ; preds = %124
212+
%130 = ptrtoint i8* %126 to i32
213+
br label %142
214+
215+
; <label>:131: ; preds = %124
216+
%132 = inttoptr i32 %112 to i8*
217+
br label %133
218+
219+
; <label>:133: ; preds = %133, %131
220+
%134 = phi i8* [ %138, %133 ], [ %132, %131 ]
221+
%135 = phi i8* [ %137, %133 ], [ %11, %131 ]
222+
%136 = load i8, i8* %135, align 1
223+
store i8 %136, i8* %134, align 1
224+
%137 = getelementptr inbounds i8, i8* %135, i32 1
225+
%138 = getelementptr inbounds i8, i8* %134, i32 1
226+
%139 = icmp eq i8* %137, %127
227+
br i1 %139, label %140, label %133
228+
229+
; <label>:140: ; preds = %133
230+
%141 = ptrtoint i8* %138 to i32
231+
br label %142
232+
233+
; <label>:142: ; preds = %140, %129
234+
%143 = phi i32 [ %112, %129 ], [ %141, %140 ]
235+
%144 = phi i32 [ %130, %129 ], [ %125, %140 ]
236+
%145 = load i8*, i8** %6, align 4
237+
store i32 %144, i32* %8, align 4
238+
store i32 %143, i32* %27, align 4
239+
store i32 %100, i32* %20, align 4
240+
%146 = icmp eq i8* %145, null
241+
br i1 %146, label %148, label %147
242+
243+
; <label>:147: ; preds = %142
244+
tail call void @Free(i8* nonnull %145) #13
245+
br label %148
246+
247+
; <label>:148: ; preds = %16, %147, %142, %43, %71, %75
248+
%149 = phi i32 [ %17, %16 ], [ %98, %147 ], [ %98, %142 ], [ %29, %43 ], [ %29, %71 ], [ %29, %75 ]
249+
ret i32 %149
250+
}
251+

llvm/test/Transforms/LoopDistribute/bounds-expansion-bug.ll

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ join:
5252
; %c = phi i32* [ %c1, %one ], [ %c2, %two ]
5353
; %a3 = bitcast i32* %a to i8* <--- new
5454
; %c5 = bitcast i32* %c to i8*
55-
; %0 = bitcast i32* undef to i8* <--- old, invalidated
55+
; %0 = bitcast i32* %a to i8* <--- old, invalidated
5656
;
5757
; 3. Finally, when C is expanded again:
5858
;
@@ -61,16 +61,20 @@ join:
6161
; %c = phi i32* [ %c1, %one ], [ %c2, %two ]
6262
; %c5 = bitcast i32* %c to i8* <--- new
6363
; %a3 = bitcast i32* %a to i8*
64-
; %0 = bitcast i32* undef to i8* <--- old, invalidated
65-
; %1 = bitcast i32* undef to i8*
64+
; %0 = bitcast i32* %c to i8* <--- old, invalidated
65+
; %1 = bitcast i32* %a to i8*
6666

6767
%a = phi i32* [%a1, %one], [%a2, %two]
6868
%c = phi i32* [%c1, %one], [%c2, %two]
6969
br label %for.body
7070

71-
72-
; CHECK: [[VALUE:%[0-9a-z]+]] = bitcast i32* undef to i8*
73-
; CHECK-NOT: [[VALUE]]
71+
; CHECK: join
72+
; CHECK: {{%[0-9a-z]+}} = bitcast i32* %c to i8*
73+
; CHECK: {{%[0-9a-z]+}} = bitcast i32* %a to i8*
74+
; CHECK: [[OLD_C:%[0-9a-z]+]] = bitcast i32* %c to i8*
75+
; CHECK: [[OLD_A:%[0-9a-z]+]] = bitcast i32* %a to i8*
76+
; CHECK-NOT: [[OLD_C]]
77+
; CHECK-NOT: [[OLD_A]]
7478

7579
for.body: ; preds = %for.body, %entry
7680
%ind = phi i64 [ 0, %join ], [ %add, %for.body ]

0 commit comments

Comments
 (0)