# HG changeset patch # User ChristianK # Date 1214770035 -7200 # Node ID 553f844ae5b9ff3a1f0e3128e939d283e97a7b2e # Parent 9967a3270837f2ad90b5156953c938ee846b2055 [svn r333] Fix inline asm bug with multiple branches to the same label. diff -r 9967a3270837 -r 553f844ae5b9 gen/asmstmt.cpp --- a/gen/asmstmt.cpp Sat Jun 28 18:37:27 2008 +0200 +++ b/gen/asmstmt.cpp Sun Jun 29 22:07:15 2008 +0200 @@ -460,10 +460,10 @@ // to a unique value that will identify the jump target in // a post-asm switch - // maps each special value to a goto destination - std::map valToGoto; + // maps each goto destination to its special value + std::map gotoToVal; - // location of the value containing the index into the valToGoto map + // location of the special value determining the goto label // will be set if post-asm dispatcher block is needed llvm::AllocaInst* jump_target; @@ -503,8 +503,12 @@ if(skip) continue; + // if we already set things up for this branch target, skip + if(gotoToVal.find(a->isBranchToLabel) != gotoToVal.end()) + continue; + // record that the jump needs to be handled in the post-asm dispatcher - valToGoto[n_goto] = a->isBranchToLabel; + gotoToVal[a->isBranchToLabel] = n_goto; // provide an in-asm target for the branch and set value Logger::println("statement '%s' references outer label '%s': creating forwarder", a->code.c_str(), a->isBranchToLabel->string); @@ -619,7 +623,7 @@ Logger::println("END ASM"); // if asm contained external branches, emit goto forwarder code - if(!valToGoto.empty()) + if(!gotoToVal.empty()) { assert(jump_target); @@ -628,17 +632,17 @@ llvm::BasicBlock* bb = llvm::BasicBlock::Create("afterasmgotoforwarder", p->topfunc(), oldend); llvm::LoadInst* val = p->ir->CreateLoad(jump_target, "__llvm_jump_target_value"); - llvm::SwitchInst* sw = p->ir->CreateSwitch(val, bb, valToGoto.size()); + llvm::SwitchInst* sw = p->ir->CreateSwitch(val, bb, gotoToVal.size()); // add all cases - std::map::iterator it, end = valToGoto.end(); - for(it = valToGoto.begin(); it != end; ++it) + std::map::iterator it, end = gotoToVal.end(); + for(it = gotoToVal.begin(); it != end; ++it) { llvm::BasicBlock* casebb = llvm::BasicBlock::Create("case", p->topfunc(), bb); - sw->addCase(llvm::ConstantInt::get(llvm::IntegerType::get(32), it->first), casebb); + sw->addCase(llvm::ConstantInt::get(llvm::IntegerType::get(32), it->second), casebb); p->scope() = IRScope(casebb,bb); - DtoGoto(&loc, it->second, enclosinghandler); + DtoGoto(&loc, it->first, enclosinghandler); } p->scope() = IRScope(bb,oldend);