diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp index 3e7eafd756e8..5e766d8e0ff8 100644 --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -2460,47 +2460,6 @@ struct MemorySanitizerVisitor : public InstVisitor { return Si; } - // Instrument: - // switch i32 %Val, label %else [ i32 0, label %A - // i32 1, label %B - // i32 2, label %C ] - // - // Typically, the switch input value (%Val) is fully initialized. - // - // Sometimes the compiler may convert (icmp + br) into a switch statement. - // MSan allows icmp eq/ne with partly initialized inputs to still result in a - // fully initialized output, if there exists a bit that is initialized in - // both inputs with a differing value. For compatibility, we support this in - // the switch instrumentation as well. Note that this edge case only applies - // if the switch input value does not match *any* of the cases (matching any - // of the cases requires an exact, fully initialized match). - // - // ShadowCases = 0 - // | propagateEqualityComparison(Val, 0) - // | propagateEqualityComparison(Val, 1) - // | propagateEqualityComparison(Val, 2)) - void visitSwitchInst(SwitchInst &SI) { - IRBuilder<> IRB(&SI); - - Value *Val = SI.getCondition(); - Value *ShadowVal = getShadow(Val); - - Value *ShadowCases = nullptr; - for (auto Case : SI.cases()) { - Value *Comparator = Case.getCaseValue(); - Value *ComparisonShadow = propagateEqualityComparison( - IRB, Val, Comparator, ShadowVal, getShadow(Comparator)); - - if (ShadowCases) - ShadowCases = IRB.CreateOr(ShadowCases, ComparisonShadow); - else - ShadowCases = ComparisonShadow; - } - - if (ShadowCases) - insertCheckShadow(ShadowCases, getOrigin(Val), &SI); - } - // Vector manipulation. void visitExtractElementInst(ExtractElementInst &I) { insertCheckShadowOf(I.getOperand(1), &I); diff --git a/llvm/test/Instrumentation/MemorySanitizer/switch-icmp.ll b/llvm/test/Instrumentation/MemorySanitizer/switch-icmp.ll index 08e56516ff5b..08c9a5a62feb 100644 --- a/llvm/test/Instrumentation/MemorySanitizer/switch-icmp.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/switch-icmp.ll @@ -8,10 +8,9 @@ ; uninitialized, if a bit is initialized in both inputs but has a different ; value. ; -; If switch has a partly uninitialized input, but it is possible to rule out -; matching any of the cases, it will use the default case instead of reporting -; use-of-uninitialized memory. This is equivalent to if the switch was replaced -; by a series of (icmp eq + br). +; TODO: since the compiler/optimizer may freely choose between (icmp eq + br) +; vs. switch, MSan's switch instrumentation also needs to be able to +; handle partly-uninitialized inputs. target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @@ -21,22 +20,8 @@ define i64 @switch_test(i32 %wii) sanitize_memory { ; CHECK-SAME: i32 [[WII:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @__msan_param_tls, align 8 ; CHECK-NEXT: call void @llvm.donothing() -; CHECK-NEXT: [[TMP3:%.*]] = xor i32 [[WII]], 42 -; CHECK-NEXT: [[TMP4:%.*]] = or i32 [[TMP1]], 0 -; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i32 [[TMP4]], 0 -; CHECK-NEXT: [[TMP6:%.*]] = xor i32 [[TMP4]], -1 -; CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP6]], [[TMP3]] -; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i32 [[TMP7]], 0 -; CHECK-NEXT: [[_MSPROP_ICMP:%.*]] = and i1 [[TMP5]], [[TMP8]] -; CHECK-NEXT: [[TMP9:%.*]] = xor i32 [[WII]], 43 -; CHECK-NEXT: [[TMP10:%.*]] = or i32 [[TMP1]], 0 -; CHECK-NEXT: [[TMP11:%.*]] = icmp ne i32 [[TMP10]], 0 -; CHECK-NEXT: [[TMP12:%.*]] = xor i32 [[TMP10]], -1 -; CHECK-NEXT: [[TMP13:%.*]] = and i32 [[TMP12]], [[TMP9]] -; CHECK-NEXT: [[TMP14:%.*]] = icmp eq i32 [[TMP13]], 0 -; CHECK-NEXT: [[_MSPROP_ICMP1:%.*]] = and i1 [[TMP11]], [[TMP14]] -; CHECK-NEXT: [[TMP15:%.*]] = or i1 [[_MSPROP_ICMP]], [[_MSPROP_ICMP1]] -; CHECK-NEXT: br i1 [[TMP15]], label %[[BB2:.*]], label %[[BB3:.*]], !prof [[PROF1:![0-9]+]] +; CHECK-NEXT: [[_MSCMP:%.*]] = icmp ne i32 [[TMP1]], 0 +; CHECK-NEXT: br i1 [[_MSCMP]], label %[[BB2:.*]], label %[[BB3:.*]], !prof [[PROF1:![0-9]+]] ; CHECK: [[BB2]]: ; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR3:[0-9]+]] ; CHECK-NEXT: unreachable