llvm.org GIT mirror llvm / 351f65d
[msan] Implement exact shadow propagation for relational ICmp. Only for integers, pointers, and vectors of those. No floats. Instrumentation seems very heavy, and may need to be replaced with some approximation in the future. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173452 91177308-0d34-0410-b5e6-96231b3b80d8 Evgeniy Stepanov 6 years ago
2 changed file(s) with 101 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
126126 cl::desc("propagate shadow through ICmpEQ and ICmpNE"),
127127 cl::Hidden, cl::init(true));
128128
129 static cl::opt ClHandleICmpExact("msan-handle-icmp-exact",
130 cl::desc("exact handling of relational integer ICmp"),
131 cl::Hidden, cl::init(true));
132
129133 static cl::opt ClStoreCleanOrigin("msan-store-clean-origin",
130134 cl::desc("store origin for clean (fully initialized) values"),
131135 cl::Hidden, cl::init(false));
11541158 setOriginForNaryOp(I);
11551159 }
11561160
1161 /// \brief Build the lowest possible value of V, taking into account V's
1162 /// uninitialized bits.
1163 Value *getLowestPossibleValue(IRBuilder<> &IRB, Value *A, Value *Sa,
1164 bool isSigned) {
1165 if (isSigned) {
1166 // Split shadow into sign bit and other bits.
1167 Value *SaOtherBits = IRB.CreateLShr(IRB.CreateShl(Sa, 1), 1);
1168 Value *SaSignBit = IRB.CreateXor(Sa, SaOtherBits);
1169 // Maximise the undefined shadow bit, minimize other undefined bits.
1170 return
1171 IRB.CreateOr(IRB.CreateAnd(A, IRB.CreateNot(SaOtherBits)), SaSignBit);
1172 } else {
1173 // Minimize undefined bits.
1174 return IRB.CreateAnd(A, IRB.CreateNot(Sa));
1175 }
1176 }
1177
1178 /// \brief Build the highest possible value of V, taking into account V's
1179 /// uninitialized bits.
1180 Value *getHighestPossibleValue(IRBuilder<> &IRB, Value *A, Value *Sa,
1181 bool isSigned) {
1182 if (isSigned) {
1183 // Split shadow into sign bit and other bits.
1184 Value *SaOtherBits = IRB.CreateLShr(IRB.CreateShl(Sa, 1), 1);
1185 Value *SaSignBit = IRB.CreateXor(Sa, SaOtherBits);
1186 // Minimise the undefined shadow bit, maximise other undefined bits.
1187 return
1188 IRB.CreateOr(IRB.CreateAnd(A, IRB.CreateNot(SaSignBit)), SaOtherBits);
1189 } else {
1190 // Maximize undefined bits.
1191 return IRB.CreateOr(A, Sa);
1192 }
1193 }
1194
1195 /// \brief Instrument relational comparisons.
1196 ///
1197 /// This function does exact shadow propagation for all relational
1198 /// comparisons of integers, pointers and vectors of those.
1199 /// FIXME: output seems suboptimal when one of the operands is a constant
1200 void handleRelationalComparisonExact(ICmpInst &I) {
1201 IRBuilder<> IRB(&I);
1202 Value *A = I.getOperand(0);
1203 Value *B = I.getOperand(1);
1204 Value *Sa = getShadow(A);
1205 Value *Sb = getShadow(B);
1206
1207 // Get rid of pointers and vectors of pointers.
1208 // For ints (and vectors of ints), types of A and Sa match,
1209 // and this is a no-op.
1210 A = IRB.CreatePointerCast(A, Sa->getType());
1211 B = IRB.CreatePointerCast(B, Sb->getType());
1212
1213 bool IsSigned = I.isSigned();
1214 Value *S1 = IRB.CreateICmp(I.getPredicate(),
1215 getLowestPossibleValue(IRB, A, Sa, IsSigned),
1216 getHighestPossibleValue(IRB, B, Sb, IsSigned));
1217 Value *S2 = IRB.CreateICmp(I.getPredicate(),
1218 getHighestPossibleValue(IRB, A, Sa, IsSigned),
1219 getLowestPossibleValue(IRB, B, Sb, IsSigned));
1220 Value *Si = IRB.CreateXor(S1, S2);
1221 setShadow(&I, Si);
1222 setOriginForNaryOp(I);
1223 }
1224
11571225 /// \brief Instrument signed relational comparisons.
11581226 ///
11591227 /// Handle (x<0) and (x>=0) comparisons (essentially, sign bit tests) by
11851253 void visitICmpInst(ICmpInst &I) {
11861254 if (ClHandleICmp && I.isEquality())
11871255 handleEqualityComparison(I);
1256 else if (ClHandleICmp && ClHandleICmpExact && I.isRelational())
1257 handleRelationalComparisonExact(I);
11881258 else if (ClHandleICmp && I.isSigned() && I.isRelational())
11891259 handleSignedRelationalComparison(I);
11901260 else
322322 ; CHECK-NOT: call void @__msan_warning
323323 ; CHECK: icmp slt
324324 ; CHECK-NOT: call void @__msan_warning
325 ; CHECK: icmp slt
326 ; CHECK-NOT: call void @__msan_warning
325327 ; CHECK: ret i1
326328
327329 define zeroext i1 @ICmpSGE(i32 %x) nounwind uwtable readnone {
330332 }
331333
332334 ; CHECK: @ICmpSGE
333 ; CHECK: icmp slt
335 ; CHECK: icmp sge
336 ; CHECK-NOT: call void @__msan_warning
337 ; CHECK: icmp sge
334338 ; CHECK-NOT: call void @__msan_warning
335339 ; CHECK: icmp sge
336340 ; CHECK-NOT: call void @__msan_warning
342346 }
343347
344348 ; CHECK: @ICmpSGT
345 ; CHECK: icmp slt
349 ; CHECK: icmp sgt
350 ; CHECK-NOT: call void @__msan_warning
351 ; CHECK: icmp sgt
346352 ; CHECK-NOT: call void @__msan_warning
347353 ; CHECK: icmp sgt
348354 ; CHECK-NOT: call void @__msan_warning
354360 }
355361
356362 ; CHECK: @ICmpSLE
357 ; CHECK: icmp slt
363 ; CHECK: icmp sle
364 ; CHECK-NOT: call void @__msan_warning
365 ; CHECK: icmp sle
358366 ; CHECK-NOT: call void @__msan_warning
359367 ; CHECK: icmp sle
360368 ; CHECK-NOT: call void @__msan_warning
372380 ; CHECK: @ICmpSLT_vector
373381 ; CHECK: icmp slt <2 x i64>
374382 ; CHECK-NOT: call void @__msan_warning
383 ; CHECK: icmp slt <2 x i64>
384 ; CHECK-NOT: call void @__msan_warning
375385 ; CHECK: icmp slt <2 x i32*>
376386 ; CHECK-NOT: call void @__msan_warning
377387 ; CHECK: ret <2 x i1>
388
389
390 ; Check that we propagate shadow for arbitrary relational comparisons
391
392 define zeroext i1 @ICmpSLENonZero(i32 %x, i32 %y) nounwind uwtable readnone {
393 entry:
394 %cmp = icmp sle i32 %x, %y
395 ret i1 %cmp
396 }
397
398 ; CHECK: @ICmpSLENonZero
399 ; CHECK: icmp sle i32
400 ; CHECK-NOT: call void @__msan_warning
401 ; CHECK: icmp sle i32
402 ; CHECK-NOT: call void @__msan_warning
403 ; CHECK: icmp sle i32
404 ; CHECK-NOT: call void @__msan_warning
405 ; CHECK: ret i1
378406
379407
380408 ; Check that loads of shadow have the same aligment as the original loads.