When substituting sunkaddrs into indirect arguments an asm, we were

walking the asm arguments once and stashing their Values.  This is
wrong because the same memory location can be in the list twice, and
if the first one has a sunkaddr substituted, the stashed value for the
second one will be wrong (use-after-free).  PR 8154.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114104 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dale Johannesen 2010-09-16 18:30:55 +00:00
parent c2ce21ad51
commit 677c6ecd08
2 changed files with 60 additions and 2 deletions

View File

@ -738,6 +738,7 @@ bool CodeGenPrepare::OptimizeInlineAsmInst(Instruction *I, CallSite CS,
bool MadeChange = false;
std::vector<TargetLowering::AsmOperandInfo> TargetConstraints = TLI->ParseConstraints(CS);
unsigned ArgNo = 0;
for (unsigned i = 0, e = TargetConstraints.size(); i != e; ++i) {
TargetLowering::AsmOperandInfo &OpInfo = TargetConstraints[i];
@ -746,9 +747,10 @@ bool CodeGenPrepare::OptimizeInlineAsmInst(Instruction *I, CallSite CS,
if (OpInfo.ConstraintType == TargetLowering::C_Memory &&
OpInfo.isIndirect) {
Value *OpVal = OpInfo.CallOperandVal;
Value *OpVal = const_cast<Value *>(CS.getArgument(ArgNo++));
MadeChange |= OptimizeMemoryInst(I, OpVal, OpVal->getType(), SunkAddrs);
}
} else if (OpInfo.Type == InlineAsm::isInput)
ArgNo++;
}
return MadeChange;

View File

@ -0,0 +1,56 @@
; RUN: llc < %s -mtriple=x86_64-unknown-freebsd8.1 -o /dev/null
; This formerly crashed, PR 8154.
module asm ".weak sem_close"
module asm ".equ sem_close, _sem_close"
module asm ".weak sem_destroy"
module asm ".equ sem_destroy, _sem_destroy"
module asm ".weak sem_getvalue"
module asm ".equ sem_getvalue, _sem_getvalue"
module asm ".weak sem_init"
module asm ".equ sem_init, _sem_init"
module asm ".weak sem_open"
module asm ".equ sem_open, _sem_open"
module asm ".weak sem_post"
module asm ".equ sem_post, _sem_post"
module asm ".weak sem_timedwait"
module asm ".equ sem_timedwait, _sem_timedwait"
module asm ".weak sem_trywait"
module asm ".equ sem_trywait, _sem_trywait"
module asm ".weak sem_unlink"
module asm ".equ sem_unlink, _sem_unlink"
module asm ".weak sem_wait"
module asm ".equ sem_wait, _sem_wait"
%struct._sem = type { i32, %struct._usem }
%struct._usem = type { i32, i32, i32 }
define void @_sem_timedwait(%struct._sem* noalias %sem) nounwind ssp {
entry:
br i1 undef, label %while.cond.preheader, label %sem_check_validity.exit
while.cond.preheader: ; preds = %entry
%tmp4 = getelementptr inbounds %struct._sem* %sem, i64 0, i32 1, i32 1
br label %while.cond
sem_check_validity.exit: ; preds = %entry
ret void
while.cond: ; preds = %while.body, %while.cond.preheader
br i1 undef, label %while.body, label %while.end
while.body: ; preds = %while.cond
%0 = call i8 asm sideeffect "\09lock ; \09\09\09cmpxchgl $2,$1 ;\09 sete\09$0 ;\09\091:\09\09\09\09# atomic_cmpset_int", "={ax},=*m,r,{ax},*m,~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %tmp4, i32 undef, i32 undef, i32* %tmp4) nounwind, !srcloc !0
br i1 undef, label %while.cond, label %return
while.end: ; preds = %while.cond
br i1 undef, label %if.end18, label %return
if.end18: ; preds = %while.end
unreachable
return: ; preds = %while.end, %while.body
ret void
}
!0 = metadata !{i32 158484}