[llvm-commits] [llvm] r168881 - in /llvm/trunk: lib/Transforms/Instrumentation/MemorySanitizer.cpp test/Instrumentation/MemorySanitizer/msan_basic.ll
Evgeniy Stepanov
eugeni.stepanov at gmail.com
Thu Nov 29 06:25:47 PST 2012
Author: eugenis
Date: Thu Nov 29 08:25:47 2012
New Revision: 168881
URL: http://llvm.org/viewvc/llvm-project?rev=168881&view=rev
Log:
[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.
Modified:
llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp
llvm/trunk/test/Instrumentation/MemorySanitizer/msan_basic.ll
Modified: llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp?rev=168881&r1=168880&r2=168881&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp Thu Nov 29 08:25:47 2012
@@ -949,9 +949,39 @@
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);
}
Modified: llvm/trunk/test/Instrumentation/MemorySanitizer/msan_basic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/MemorySanitizer/msan_basic.ll?rev=168881&r1=168880&r2=168881&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/MemorySanitizer/msan_basic.ll (original)
+++ llvm/trunk/test/Instrumentation/MemorySanitizer/msan_basic.ll Thu Nov 29 08:25:47 2012
@@ -235,6 +235,53 @@
; 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 {
More information about the llvm-commits
mailing list