Revert "[msan] Switch switch() from strict handling to (icmp eq)-style handling" (#180636)

Reverts llvm/llvm-project#179851

Breaks https://lab.llvm.org/buildbot/#/builders/164/builds/18551 and
https://lab.llvm.org/buildbot/#/builders/94/builds/15188
This commit is contained in:
Andrew Lazarev 2026-02-09 16:23:52 -08:00 committed by GitHub
parent 481f248e08
commit cfbb9a66ae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 5 additions and 61 deletions

View File

@ -2460,47 +2460,6 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
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);

View File

@ -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