llvm.org GIT mirror llvm / 72349b2
[LVI] Handle conditions in the form of (cond1 && cond2) Teach LVI how to gather information from conditions in the form of (cond1 && cond2). Our out-of-tree front-end emits range checks in this form. Reviewed By: sanjoy Differential Revision: http://reviews.llvm.org/D23200 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278231 91177308-0d34-0410-b5e6-96231b3b80d8 Artur Pilipenko 3 years ago
2 changed file(s) with 136 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
11661166 return true;
11671167 }
11681168
1169 LVILatticeVal getValueFromCondition(Value *Val, Value *Cond, bool isTrueDest) {
1170 assert(Cond && "precondition");
1171
1172 // For now we only support ICmpInst conditions
1173 ICmpInst *ICI = dyn_cast(Cond);
1174 if (!ICI)
1175 return LVILatticeVal::getOverdefined();
1176
1169 static LVILatticeVal getValueFromICmpCondition(Value *Val, ICmpInst *ICI,
1170 bool isTrueDest) {
11771171 Value *LHS = ICI->getOperand(0);
11781172 Value *RHS = ICI->getOperand(1);
11791173 CmpInst::Predicate Predicate = ICI->getPredicate();
12301224 }
12311225
12321226 return LVILatticeVal::getOverdefined();
1227 }
1228
1229 static LVILatticeVal
1230 getValueFromCondition(Value *Val, Value *Cond, bool isTrueDest,
1231 DenseMap &Visited);
1232
1233 static LVILatticeVal
1234 getValueFromConditionImpl(Value *Val, Value *Cond, bool isTrueDest,
1235 DenseMap &Visited) {
1236 if (ICmpInst *ICI = dyn_cast(Cond))
1237 return getValueFromICmpCondition(Val, ICI, isTrueDest);
1238
1239 // Handle conditions in the form of (cond1 && cond2), we know that on the
1240 // true dest path both of the conditions hold.
1241 if (!isTrueDest)
1242 return LVILatticeVal::getOverdefined();
1243
1244 BinaryOperator *BO = dyn_cast(Cond);
1245 if (!BO || BO->getOpcode() != BinaryOperator::And)
1246 return LVILatticeVal::getOverdefined();
1247
1248 auto RHS = getValueFromCondition(Val, BO->getOperand(0), isTrueDest, Visited);
1249 auto LHS = getValueFromCondition(Val, BO->getOperand(1), isTrueDest, Visited);
1250 return intersect(RHS, LHS);
1251 }
1252
1253 static LVILatticeVal
1254 getValueFromCondition(Value *Val, Value *Cond, bool isTrueDest,
1255 DenseMap &Visited) {
1256 auto I = Visited.find(Cond);
1257 if (I != Visited.end())
1258 return I->second;
1259 return Visited[Cond] = getValueFromConditionImpl(Val, Cond, isTrueDest,
1260 Visited);
1261 }
1262
1263 LVILatticeVal getValueFromCondition(Value *Val, Value *Cond, bool isTrueDest) {
1264 assert(Cond && "precondition");
1265 DenseMap Visited;
1266 return getValueFromCondition(Val, Cond, isTrueDest, Visited);
12331267 }
12341268
12351269 /// \brief Compute the value of Val on the edge BBFrom -> BBTo. Returns false if
9898 %add = add i32 %a, ptrtoint (i32* @b to i32)
9999 ret void
100100 }
101
102 ; Check that we can gather information for conditions is the form of
103 ; and ( i s< 100, Unknown )
104 ; CHECK-LABEL: @test7(
105 define void @test7(i32 %a, i1 %flag) {
106 entry:
107 %cmp.1 = icmp slt i32 %a, 100
108 %cmp = and i1 %cmp.1, %flag
109 br i1 %cmp, label %bb, label %exit
110
111 bb:
112 ; CHECK: %add = add nsw i32 %a, 1
113 %add = add i32 %a, 1
114 br label %exit
115
116 exit:
117 ret void
118 }
119
120 ; Check that we can gather information for conditions is the form of
121 ; and ( i s< 100, i s> 0 )
122 ; CHECK-LABEL: @test8(
123 define void @test8(i32 %a) {
124 entry:
125 %cmp.1 = icmp slt i32 %a, 100
126 %cmp.2 = icmp sgt i32 %a, 0
127 %cmp = and i1 %cmp.1, %cmp.2
128 br i1 %cmp, label %bb, label %exit
129
130 bb:
131 ; CHECK: %add = add nuw nsw i32 %a, 1
132 %add = add i32 %a, 1
133 br label %exit
134
135 exit:
136 ret void
137 }
138
139 ; Check that for conditions is the form of cond1 && cond2 we don't mistakenly
140 ; assume that !cond1 && !cond2 holds down to false path.
141 ; CHECK-LABEL: @test8_neg(
142 define void @test8_neg(i32 %a) {
143 entry:
144 %cmp.1 = icmp sge i32 %a, 100
145 %cmp.2 = icmp sle i32 %a, 0
146 %cmp = and i1 %cmp.1, %cmp.2
147 br i1 %cmp, label %exit, label %bb
148
149 bb:
150 ; CHECK: %add = add i32 %a, 1
151 %add = add i32 %a, 1
152 br label %exit
153
154 exit:
155 ret void
156 }
157
158 ; Check that we can gather information for conditions is the form of
159 ; and ( i s< 100, and (i s> 0, Unknown )
160 ; CHECK-LABEL: @test9(
161 define void @test9(i32 %a, i1 %flag) {
162 entry:
163 %cmp.1 = icmp slt i32 %a, 100
164 %cmp.2 = icmp sgt i32 %a, 0
165 %cmp.3 = and i1 %cmp.2, %flag
166 %cmp = and i1 %cmp.1, %cmp.3
167 br i1 %cmp, label %bb, label %exit
168
169 bb:
170 ; CHECK: %add = add nuw nsw i32 %a, 1
171 %add = add i32 %a, 1
172 br label %exit
173
174 exit:
175 ret void
176 }
177
178 ; Check that we can gather information for conditions is the form of
179 ; and ( i s< Unknown, ... )
180 ; CHECK-LABEL: @test10(
181 define void @test10(i32 %a, i32 %b, i1 %flag) {
182 entry:
183 %cmp.1 = icmp slt i32 %a, %b
184 %cmp = and i1 %cmp.1, %flag
185 br i1 %cmp, label %bb, label %exit
186
187 bb:
188 ; CHECK: %add = add nsw i32 %a, 1
189 %add = add i32 %a, 1
190 br label %exit
191
192 exit:
193 ret void
194 }