[LLVMdev] Curiosity about transform changes under Sanitizers (Was: [PATCH] Disable branch folding with MemorySanitizer)
Evgeniy Stepanov
eugeni.stepanov at gmail.com
Tue Nov 19 08:55:11 PST 2013
The root cause of those issues is the fact that sanitizers verify
C++-level semantics with LLVM IR level instrumentation. For example,
speculative loads are OK in IR if it can be proved that the load won't
trap, but in C++ it would be a data race.
On Tue, Nov 19, 2013 at 8:38 PM, Kostya Serebryany <kcc at google.com> wrote:
>
>
>
> On Tue, Nov 19, 2013 at 8:25 PM, David Blaikie <dblaikie at gmail.com> wrote:
>>
>> Just moving this branch of the thread out of the review because I don't
>> want to derail the review thread...
>>
>> Kostya - why are these two cases not optimization bugs in general? (why do
>> they only affect sanitizers?)
>
>
> The recent case from mozilla
> (https://code.google.com/p/thread-sanitizer/issues/detail?id=40#c2) is a
> legal
> optimization -- it hoists a safe load (i.e. a load which is known not to
> fail) out of conditional branch.
> It reduces the number of basic blocks and branches, and so I think it's good
> in general.
> I can't imagine a case where this optimization will break a valid program.
> Which is the second one you are referring to?
>
> --kcc
>
>>
>>
>>
>>
>> On Mon, Nov 18, 2013 at 8:37 PM, Kostya Serebryany <kcc at google.com> wrote:
>>>
>>> And we've been just informed by the mozilla folks about yet another case
>>> of optimization being hostile to sanitizers:
>>> hoisting a safe load out of conditional branch introduces a race which
>>> tsan happily reports.
>>> https://code.google.com/p/thread-sanitizer/issues/detail?id=40#c2
>>>
>>> --kcc
>>>
>>>
>>> On Tue, Nov 19, 2013 at 8:06 AM, Kostya Serebryany <kcc at google.com>
>>> wrote:
>>>>
>>>>
>>>>
>>>>
>>>> On Tue, Nov 19, 2013 at 1:27 AM, David Blaikie <dblaikie at gmail.com>
>>>> wrote:
>>>>>
>>>>> Do we have precedence for this kind of change (where sanitizers affect
>>>>> optimizations in arbitrary internal ways - not simply by enabling/disabling
>>>>> certain passes)?
>>>>
>>>>
>>>> Yes. AddressSanitizer and ThreadSanitizer disable load widening that
>>>> would create a partially out-of-bounds or a racy access.
>>>> See lib/Analysis/MemoryDependenceAnalysis.cpp (search for
>>>> Attribute::SanitizeAddress and Attribute::SanitizeThread).
>>>> This case with MemorySanitizer is slightly different because we are not
>>>> fighting a false positive, but rather a debug-info-damaging optimization.
>>>>
>>>> --kcc
>>>>
>>>>>
>>>>> If not, does this need some deeper discussion about alternatives (is it
>>>>> important that we be able to produce equivalent code without the sanitizers
>>>>> enabled?)?
>>>>>
>>>>>
>>>>> On Mon, Nov 18, 2013 at 7:02 AM, Evgeniy Stepanov <eugenis at google.com>
>>>>> wrote:
>>>>>>
>>>>>> Branch folding optimization often leads to confusing MSan reports due
>>>>>> to lost debug info.
>>>>>> For example,
>>>>>> 1: if (x < 0)
>>>>>> 2: if (y < 0)
>>>>>> 3: do_something();
>>>>>> is transformed into something like
>>>>>> %0 = and i32 %y, %x
>>>>>> %1 = icmp slt i32 %0, 0
>>>>>> br i1 %1, label %if.then2, label %if.end3
>>>>>> where all 3 instructions are associated with line 1.
>>>>>>
>>>>>> This patch disables folding of conditional branches in functions with
>>>>>> sanitize_memory attribute.
>>>>>>
>>>>>> http://llvm-reviews.chandlerc.com/D2214
>>>>>>
>>>>>> Files:
>>>>>> lib/Transforms/Utils/SimplifyCFG.cpp
>>>>>> test/Transforms/SimplifyCFG/branch-fold-msan.ll
>>>>>>
>>>>>> Index: lib/Transforms/Utils/SimplifyCFG.cpp
>>>>>> ===================================================================
>>>>>> --- lib/Transforms/Utils/SimplifyCFG.cpp
>>>>>> +++ lib/Transforms/Utils/SimplifyCFG.cpp
>>>>>> @@ -1967,6 +1967,13 @@
>>>>>> bool llvm::FoldBranchToCommonDest(BranchInst *BI) {
>>>>>> BasicBlock *BB = BI->getParent();
>>>>>>
>>>>>> + // This optimization results in confusing MemorySanitizer reports.
>>>>>> Use of
>>>>>> + // uninitialized value in this branch instruction is reported with
>>>>>> the
>>>>>> + // predecessor's debug location.
>>>>>> + if (BB->getParent()->hasFnAttribute(Attribute::SanitizeMemory) &&
>>>>>> + BI->isConditional())
>>>>>> + return false;
>>>>>> +
>>>>>> Instruction *Cond = 0;
>>>>>> if (BI->isConditional())
>>>>>> Cond = dyn_cast<Instruction>(BI->getCondition());
>>>>>> Index: test/Transforms/SimplifyCFG/branch-fold-msan.ll
>>>>>> ===================================================================
>>>>>> --- test/Transforms/SimplifyCFG/branch-fold-msan.ll
>>>>>> +++ test/Transforms/SimplifyCFG/branch-fold-msan.ll
>>>>>> @@ -0,0 +1,29 @@
>>>>>> +; RUN: opt < %s -simplifycfg -S | FileCheck %s
>>>>>> +
>>>>>> +declare void @callee()
>>>>>> +
>>>>>> +; Test that conditional branches are not folded with sanitize_memory.
>>>>>> +define void @caller(i32 %x, i32 %y) sanitize_memory {
>>>>>> +; CHECK: define void @caller(i32 [[X:%.*]], i32 [[Y:%.*]])
>>>>>> +; CHECK: icmp slt i32 {{.*}}[[X]]
>>>>>> +; CHECK: icmp slt i32 {{.*}}[[Y]]
>>>>>> +; CHECK: ret void
>>>>>> +
>>>>>> +entry:
>>>>>> + %cmp = icmp slt i32 %x, 0
>>>>>> + br i1 %cmp, label %if.then, label %if.end3
>>>>>> +
>>>>>> +if.then: ; preds = %entry
>>>>>> + %cmp1 = icmp slt i32 %y, 0
>>>>>> + br i1 %cmp1, label %if.then2, label %if.end
>>>>>> +
>>>>>> +if.then2: ; preds = %if.then
>>>>>> + call void @callee()
>>>>>> + br label %if.end
>>>>>> +
>>>>>> +if.end: ; preds =
>>>>>> %if.then2, %if.then
>>>>>> + br label %if.end3
>>>>>> +
>>>>>> +if.end3: ; preds = %if.end,
>>>>>> %entry
>>>>>> + ret void
>>>>>> +}
>>>>>>
>>>>>> _______________________________________________
>>>>>> llvm-commits mailing list
>>>>>> llvm-commits at cs.uiuc.edu
>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> llvm-commits mailing list
>>>>> llvm-commits at cs.uiuc.edu
>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>>>>
>>>>
>>>
>>
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
More information about the llvm-dev
mailing list