mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-12 22:53:08 +00:00
[msan] Propagate shadow through (x<0) and (x>=0) comparisons.
This is a special case of signed relational comparison where result only depends on the sign of x. llvm-svn: 168881
This commit is contained in:
parent
fc6164c985
commit
fafa2ae4b6
@ -949,9 +949,39 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
|
||||
setOriginForNaryOp(I);
|
||||
}
|
||||
|
||||
/// \brief Instrument signed relational comparisons.
|
||||
///
|
||||
/// Handle (x<0) and (x>=0) comparisons (essentially, sign bit tests) by
|
||||
/// propagating the highest bit of the shadow. Everything else is delegated
|
||||
/// to handleShadowOr().
|
||||
void handleSignedRelationalComparison(ICmpInst &I) {
|
||||
Constant *constOp0 = dyn_cast<Constant>(I.getOperand(0));
|
||||
Constant *constOp1 = dyn_cast<Constant>(I.getOperand(1));
|
||||
Value* op = NULL;
|
||||
CmpInst::Predicate pre = I.getPredicate();
|
||||
if (constOp0 && constOp0->isNullValue() &&
|
||||
(pre == CmpInst::ICMP_SGT || pre == CmpInst::ICMP_SLE)) {
|
||||
op = I.getOperand(1);
|
||||
} else if (constOp1 && constOp1->isNullValue() &&
|
||||
(pre == CmpInst::ICMP_SLT || pre == CmpInst::ICMP_SGE)) {
|
||||
op = I.getOperand(0);
|
||||
}
|
||||
if (op) {
|
||||
IRBuilder<> IRB(&I);
|
||||
Value* Shadow =
|
||||
IRB.CreateICmpSLT(getShadow(op), getCleanShadow(op), "_msprop_icmpslt");
|
||||
setShadow(&I, Shadow);
|
||||
setOrigin(&I, getOrigin(op));
|
||||
} else {
|
||||
handleShadowOr(I);
|
||||
}
|
||||
}
|
||||
|
||||
void visitICmpInst(ICmpInst &I) {
|
||||
if (ClHandleICmp && I.isEquality())
|
||||
handleEqualityComparison(I);
|
||||
else if (ClHandleICmp && I.isSigned() && I.isRelational())
|
||||
handleSignedRelationalComparison(I);
|
||||
else
|
||||
handleShadowOr(I);
|
||||
}
|
||||
|
@ -235,6 +235,53 @@ entry:
|
||||
; CHECK: }
|
||||
|
||||
|
||||
; Check that we propagate shadow for x<0, x>=0, etc (i.e. sign bit tests)
|
||||
|
||||
define zeroext i1 @ICmpSLT(i32 %x) nounwind uwtable readnone {
|
||||
%1 = icmp slt i32 %x, 0
|
||||
ret i1 %1
|
||||
}
|
||||
|
||||
; CHECK: define zeroext i1 @ICmpSLT
|
||||
; CHECK: icmp slt
|
||||
; CHECK: icmp slt
|
||||
; CHECK-NOT: br
|
||||
; CHECK: }
|
||||
|
||||
define zeroext i1 @ICmpSGE(i32 %x) nounwind uwtable readnone {
|
||||
%1 = icmp sge i32 %x, 0
|
||||
ret i1 %1
|
||||
}
|
||||
|
||||
; CHECK: define zeroext i1 @ICmpSGE
|
||||
; CHECK: icmp slt
|
||||
; CHECK: icmp sge
|
||||
; CHECK-NOT: br
|
||||
; CHECK: }
|
||||
|
||||
define zeroext i1 @ICmpSGT(i32 %x) nounwind uwtable readnone {
|
||||
%1 = icmp sgt i32 0, %x
|
||||
ret i1 %1
|
||||
}
|
||||
|
||||
; CHECK: define zeroext i1 @ICmpSGT
|
||||
; CHECK: icmp slt
|
||||
; CHECK: icmp sgt
|
||||
; CHECK-NOT: br
|
||||
; CHECK: }
|
||||
|
||||
define zeroext i1 @ICmpSLE(i32 %x) nounwind uwtable readnone {
|
||||
%1 = icmp sle i32 0, %x
|
||||
ret i1 %1
|
||||
}
|
||||
|
||||
; CHECK: define zeroext i1 @ICmpSLE
|
||||
; CHECK: icmp slt
|
||||
; CHECK: icmp sle
|
||||
; CHECK-NOT: br
|
||||
; CHECK: }
|
||||
|
||||
|
||||
; Check that loads from shadow have the same aligment as the original loads.
|
||||
|
||||
define i32 @ShadowLoadAlignmentLarge() nounwind uwtable {
|
||||
|
Loading…
x
Reference in New Issue
Block a user