[msan] Don't check divisor shadow in fdiv.

Summary:
Floating point division by zero or even undef does not have undefined
behavior and may occur due to optimizations.

Fixes https://bugs.llvm.org/show_bug.cgi?id=37523.

Reviewers: kcc

Subscribers: hiraditya, llvm-commits

Differential Revision: https://reviews.llvm.org/D47085

llvm-svn: 332761
This commit is contained in:
Evgeniy Stepanov 2018-05-18 20:19:53 +00:00
parent fd2b373e39
commit 25780c4ed3
2 changed files with 25 additions and 7 deletions

View File

@ -1841,7 +1841,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
void visitSub(BinaryOperator &I) { handleShadowOr(I); }
void visitXor(BinaryOperator &I) { handleShadowOr(I); }
void handleDiv(Instruction &I) {
void handleIntegerDiv(Instruction &I) {
IRBuilder<> IRB(&I);
// Strict on the second argument.
insertShadowCheck(I.getOperand(1), &I);
@ -1849,12 +1849,15 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
setOrigin(&I, getOrigin(&I, 0));
}
void visitUDiv(BinaryOperator &I) { handleDiv(I); }
void visitSDiv(BinaryOperator &I) { handleDiv(I); }
void visitFDiv(BinaryOperator &I) { handleDiv(I); }
void visitURem(BinaryOperator &I) { handleDiv(I); }
void visitSRem(BinaryOperator &I) { handleDiv(I); }
void visitFRem(BinaryOperator &I) { handleDiv(I); }
void visitUDiv(BinaryOperator &I) { handleIntegerDiv(I); }
void visitSDiv(BinaryOperator &I) { handleIntegerDiv(I); }
void visitURem(BinaryOperator &I) { handleIntegerDiv(I); }
void visitSRem(BinaryOperator &I) { handleIntegerDiv(I); }
// Floating point division is side-effect free. We can not require that the
// divisor is fully initialized and must propagate shadow. See PR37523.
void visitFDiv(BinaryOperator &I) { handleShadowOr(I); }
void visitFRem(BinaryOperator &I) { handleShadowOr(I); }
/// Instrument == and != comparisons.
///

View File

@ -417,6 +417,21 @@ entry:
; CHECK-NOT: icmp
; CHECK: ret i32
; Check that fdiv, unlike udiv, simply propagates shadow.
define float @FDiv(float %a, float %b) nounwind uwtable readnone sanitize_memory {
entry:
%c = fdiv float %a, %b
ret float %c
}
; CHECK-LABEL: @FDiv
; CHECK: %[[SA:.*]] = load i32,{{.*}}@__msan_param_tls
; CHECK: %[[SB:.*]] = load i32,{{.*}}@__msan_param_tls
; CHECK: %[[SC:.*]] = or i32 %[[SB]], %[[SA]]
; CHECK: = fdiv float
; CHECK: store i32 %[[SC]], i32* {{.*}}@__msan_retval_tls
; CHECK: ret float
; Check that we propagate shadow for x<0, x>=0, etc (i.e. sign bit tests)