diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 1eb251d0a68..483b051bdcf 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -5218,28 +5218,32 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { } case Intrinsic::lifetime_start: case Intrinsic::lifetime_end: { - // Stack coloring is not enabled in O0, discard region information. - if (TM.getOptLevel() == CodeGenOpt::None) { - if (Intrinsic == Intrinsic::lifetime_start) - setValue(&I, DAG.getUNDEF(TLI.getPointerTy())); - return 0; - } - SDValue Ops[2]; - AllocaInst *LifetimeObject =dyn_cast_or_null( - GetUnderlyingObject(I.getArgOperand(1), TD)); - // Could not find an Alloca. - if (!LifetimeObject) - return 0; - - int FI = FuncInfo.StaticAllocaMap[LifetimeObject]; - Ops[0] = getRoot(); - Ops[1] = DAG.getFrameIndex(FI, TLI.getPointerTy(), true); bool IsStart = (Intrinsic == Intrinsic::lifetime_start); - unsigned Opcode = (IsStart ? ISD::LIFETIME_START : ISD::LIFETIME_END); + // Stack coloring is not enabled in O0, discard region information. + if (TM.getOptLevel() == CodeGenOpt::None) + return 0; - Res = DAG.getNode(Opcode, dl, MVT::Other, Ops, 2); - DAG.setRoot(Res); - return 0; + SmallVector Allocas; + GetUnderlyingObjects(I.getArgOperand(1), Allocas, TD); + + for (SmallVector::iterator Object = Allocas.begin(), + E = Allocas.end(); Object != E; ++Object) { + AllocaInst *LifetimeObject = dyn_cast_or_null(*Object); + + // Could not find an Alloca. + if (!LifetimeObject) + continue; + + int FI = FuncInfo.StaticAllocaMap[LifetimeObject]; + + SDValue Ops[2]; + Ops[0] = getRoot(); + Ops[1] = DAG.getFrameIndex(FI, TLI.getPointerTy(), true); + unsigned Opcode = (IsStart ? ISD::LIFETIME_START : ISD::LIFETIME_END); + + Res = DAG.getNode(Opcode, dl, MVT::Other, Ops, 2); + DAG.setRoot(Res); + } } case Intrinsic::invariant_start: // Discard region information. diff --git a/test/CodeGen/X86/StackColoring.ll b/test/CodeGen/X86/StackColoring.ll index 26ed0ecc0c9..42235a03e3a 100644 --- a/test/CodeGen/X86/StackColoring.ll +++ b/test/CodeGen/X86/StackColoring.ll @@ -262,6 +262,41 @@ entry: ret void } +;YESCOLOR: subq $272, %rsp +;NOCOLOR: subq $272, %rsp +define i32 @func_phi_lifetime(i32 %in, i1 %d) { +entry: + %a = alloca [17 x i8*], align 8 + %a2 = alloca [16 x i8*], align 8 + %b = bitcast [17 x i8*]* %a to i8* + %b2 = bitcast [16 x i8*]* %a2 to i8* + %t1 = call i32 @foo(i32 %in, i8* %b) + %t2 = call i32 @foo(i32 %in, i8* %b) + call void @llvm.lifetime.end(i64 -1, i8* %b) + br i1 %d, label %bb0, label %bb1 + +bb0: + %I1 = bitcast [17 x i8*]* %a to i8* + br label %bb2 + +bb1: + %I2 = bitcast [16 x i8*]* %a2 to i8* + br label %bb2 + +bb2: + %split = phi i8* [ %I1, %bb0 ], [ %I2, %bb1 ] + call void @llvm.lifetime.start(i64 -1, i8* %split) + %t3 = call i32 @foo(i32 %in, i8* %b2) + %t4 = call i32 @foo(i32 %in, i8* %b2) + %t5 = add i32 %t1, %t2 + %t6 = add i32 %t3, %t4 + %t7 = add i32 %t5, %t6 + call void @llvm.lifetime.end(i64 -1, i8* %split) + ret i32 %t7 +bb3: + ret i32 0 +} + declare void @bar([100 x i32]* , [100 x i32]*) nounwind declare void @llvm.lifetime.start(i64, i8* nocapture) nounwind