From 12d152f61ccef9a2c0372ba39be7cf416c6e1a9e Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 13 Feb 2009 23:35:32 +0000 Subject: [PATCH] fix rdar://6586493, a bug in codegen of the GNU missing-?:-true-value extension. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64505 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGExprScalar.cpp | 28 +++++++++++++++++++--------- test/CodeGen/conditional-gnu-ext.c | 6 ++++++ 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 962c2ebacc..164d57eb71 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -1270,20 +1270,30 @@ VisitConditionalOperator(const ConditionalOperator *E) { llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end"); Value *CondVal = 0; - // If we have the GNU missing condition extension, evaluate the conditional - // and then convert it to bool the hard way. We do this explicitly - // because we need the unconverted value for the missing middle value of - // the ?:. - if (E->getLHS() == 0) { + // If we don't have the GNU missing condition extension, emit a branch on + // bool the normal way. + if (E->getLHS()) { + // Otherwise, just use EmitBranchOnBoolExpr to get small and simple code for + // the branch on bool. + CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock); + } else { + // Otherwise, for the ?: extension, evaluate the conditional and then + // convert it to bool the hard way. We do this explicitly because we need + // the unconverted value for the missing middle value of the ?:. CondVal = CGF.EmitScalarExpr(E->getCond()); + + // In some cases, EmitScalarConversion will delete the "CondVal" expression + // if there are no extra uses (an optimization). Inhibit this by making an + // extra dead use, because we're going to add a use of CondVal later. We + // don't use the builder for this, because we don't want it to get optimized + // away. This leaves dead code, but the ?: extension isn't common. + new llvm::BitCastInst(CondVal, CondVal->getType(), "dummy?:holder", + Builder.GetInsertBlock()); + Value *CondBoolVal = CGF.EmitScalarConversion(CondVal, E->getCond()->getType(), CGF.getContext().BoolTy); Builder.CreateCondBr(CondBoolVal, LHSBlock, RHSBlock); - } else { - // Otherwise, just use EmitBranchOnBoolExpr to get small and simple code for - // the branch on bool. - CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock); } CGF.EmitBlock(LHSBlock); diff --git a/test/CodeGen/conditional-gnu-ext.c b/test/CodeGen/conditional-gnu-ext.c index d4ae330949..c3ff2bdccc 100644 --- a/test/CodeGen/conditional-gnu-ext.c +++ b/test/CodeGen/conditional-gnu-ext.c @@ -4,3 +4,9 @@ int foo(int x, short y) { return x ?: y; } + +// rdar://6586493 +float test(float x, int Y) { + return Y != 0 ? : x; +} + -- 2.40.0