[PATCH] Disable tail merge of call sites when building with any sanitizer
Evgeniy Stepanov
eugenis at google.com
Mon Nov 18 07:31:56 PST 2013
Merging call sites leads to very poor and misleading stack traces. They have wrong line numbers for some of the frames, but in a very non-obvious way, which makes reasoning about such reports very difficult.
http://llvm-reviews.chandlerc.com/D2215
Files:
lib/CodeGen/BranchFolding.h
lib/CodeGen/BranchFolding.cpp
test/CodeGen/X86/tail-merge-msan.ll
Index: lib/CodeGen/BranchFolding.h
===================================================================
--- lib/CodeGen/BranchFolding.h
+++ lib/CodeGen/BranchFolding.h
@@ -86,6 +86,7 @@
std::vector<SameTailElt> SameTails;
bool EnableTailMerge;
+ bool EnableTailMergeCalls;
bool EnableHoistCommonCode;
const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI;
Index: lib/CodeGen/BranchFolding.cpp
===================================================================
--- lib/CodeGen/BranchFolding.cpp
+++ lib/CodeGen/BranchFolding.cpp
@@ -90,7 +90,6 @@
getAnalysisIfAvailable<MachineModuleInfo>());
}
-
BranchFolder::BranchFolder(bool defaultEnableTailMerge, bool CommonHoist) {
switch (FlagEnableTailMerge) {
case cl::BOU_UNSET: EnableTailMerge = defaultEnableTailMerge; break;
@@ -169,7 +168,7 @@
return true;
}
-/// OptimizeFunction - Perhaps branch folding, tail merging and other
+/// OptimizeFunction - Perform branch folding, tail merging and other
/// CFG optimizations on the given function.
bool BranchFolder::OptimizeFunction(MachineFunction &MF,
const TargetInstrInfo *tii,
@@ -184,6 +183,13 @@
MMI = mmi;
RS = NULL;
+ // Tail merging code that contains function calls breaks symbolization of
+ // stack traces.
+ EnableTailMergeCalls =
+ !MF.getFunction()->hasFnAttribute(Attribute::SanitizeAddress) &&
+ !MF.getFunction()->hasFnAttribute(Attribute::SanitizeMemory) &&
+ !MF.getFunction()->hasFnAttribute(Attribute::SanitizeThread);
+
// Use a RegScavenger to help update liveness when required.
MachineRegisterInfo &MRI = MF.getRegInfo();
if (MRI.tracksLiveness() && TRI->trackLivenessAfterRegAlloc(MF))
@@ -305,7 +311,8 @@
static unsigned ComputeCommonTailLength(MachineBasicBlock *MBB1,
MachineBasicBlock *MBB2,
MachineBasicBlock::iterator &I1,
- MachineBasicBlock::iterator &I2) {
+ MachineBasicBlock::iterator &I2,
+ bool EnableTailMergeCalls) {
I1 = MBB1->end();
I2 = MBB2->end();
@@ -337,7 +344,7 @@
--I2;
}
// I1, I2==first (untested) non-DBGs preceding known match
- if (!I1->isIdenticalTo(I2) ||
+ if (!I1->isIdenticalTo(I2) || (!EnableTailMergeCalls && I1->isCall()) ||
// FIXME: This check is dubious. It's used to get around a problem where
// people incorrectly expect inline asm directives to remain in the same
// relative order. This is untenable because normal compiler
@@ -519,15 +526,16 @@
/// and decide if it would be profitable to merge those tails. Return the
/// length of the common tail and iterators to the first common instruction
/// in each block.
-static bool ProfitableToMerge(MachineBasicBlock *MBB1,
- MachineBasicBlock *MBB2,
+static bool ProfitableToMerge(MachineBasicBlock *MBB1, MachineBasicBlock *MBB2,
unsigned minCommonTailLength,
unsigned &CommonTailLen,
MachineBasicBlock::iterator &I1,
MachineBasicBlock::iterator &I2,
MachineBasicBlock *SuccBB,
- MachineBasicBlock *PredBB) {
- CommonTailLen = ComputeCommonTailLength(MBB1, MBB2, I1, I2);
+ MachineBasicBlock *PredBB,
+ bool EnableTailMergeCalls) {
+ CommonTailLen =
+ ComputeCommonTailLength(MBB1, MBB2, I1, I2, EnableTailMergeCalls);
if (CommonTailLen == 0)
return false;
DEBUG(dbgs() << "Common tail length of BB#" << MBB1->getNumber()
@@ -604,9 +612,8 @@
for (MPIterator I = prior(CurMPIter); I->getHash() == CurHash ; --I) {
unsigned CommonTailLen;
if (ProfitableToMerge(CurMPIter->getBlock(), I->getBlock(),
- minCommonTailLength,
- CommonTailLen, TrialBBI1, TrialBBI2,
- SuccBB, PredBB)) {
+ minCommonTailLength, CommonTailLen, TrialBBI1,
+ TrialBBI2, SuccBB, PredBB, EnableTailMergeCalls)) {
if (CommonTailLen > maxCommonTailLength) {
SameTails.clear();
maxCommonTailLength = CommonTailLen;
Index: test/CodeGen/X86/tail-merge-msan.ll
===================================================================
--- test/CodeGen/X86/tail-merge-msan.ll
+++ test/CodeGen/X86/tail-merge-msan.ll
@@ -0,0 +1,80 @@
+; RUN: llc < %s -march=x86-64 -mtriple=x86_64-unknown-linux-gnu -asm-verbose=false | FileCheck %s
+
+declare void @callee()
+
+; Test that call sites are not tail merged with sanitize_address
+
+define i32 @caller1(i32 %x) sanitize_address {
+; CHECK: caller1:
+; CHECK: callq callee
+; CHECK: callq callee
+; CHECK: ret
+entry:
+ switch i32 %x, label %if.end3 [
+ i32 1, label %if.then
+ i32 2, label %if.then2
+ ]
+
+if.then: ; preds = %entry
+ tail call void @callee()
+ br label %if.end3
+
+if.then2: ; preds = %entry
+ tail call void @callee()
+ br label %if.end3
+
+if.end3: ; preds = %entry, %if.then2, %if.then
+ ret i32 0
+}
+
+
+; Test that call sites are not tail merged with sanitize_memory
+
+define i32 @caller2(i32 %x) sanitize_memory {
+; CHECK: caller2:
+; CHECK: callq callee
+; CHECK: callq callee
+; CHECK: ret
+entry:
+ switch i32 %x, label %if.end3 [
+ i32 1, label %if.then
+ i32 2, label %if.then2
+ ]
+
+if.then: ; preds = %entry
+ tail call void @callee()
+ br label %if.end3
+
+if.then2: ; preds = %entry
+ tail call void @callee()
+ br label %if.end3
+
+if.end3: ; preds = %entry, %if.then2, %if.then
+ ret i32 0
+}
+
+
+; Test that call sites are not tail merged with sanitize_thread
+
+define i32 @caller3(i32 %x) sanitize_thread {
+; CHECK: caller3:
+; CHECK: callq callee
+; CHECK: callq callee
+; CHECK: ret
+entry:
+ switch i32 %x, label %if.end3 [
+ i32 1, label %if.then
+ i32 2, label %if.then2
+ ]
+
+if.then: ; preds = %entry
+ tail call void @callee()
+ br label %if.end3
+
+if.then2: ; preds = %entry
+ tail call void @callee()
+ br label %if.end3
+
+if.end3: ; preds = %entry, %if.then2, %if.then
+ ret i32 0
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2215.1.patch
Type: text/x-patch
Size: 6781 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131118/de35fafe/attachment.bin>
More information about the llvm-commits
mailing list