r183821 - Add support for complex compound assignments where the LHS is a scalar.
Bill Schmidt
wschmidt at linux.vnet.ibm.com
Wed Jun 12 07:45:27 PDT 2013
Hi Eli,
The change to volatile-1.c fails on powerpc64-unknown-linux-gnu:
/home/wschmidt/llvm/llvm-test3/tools/clang/test/CodeGen/volatile-1.c:317:11: error: expected string not found in input
// CHECK: define i32 @test2()
^
<stdin>:206:1: note: scanning from here
}
^
<stdin>:211:9: note: possible intended match here
define signext i32 @test2() #0 {
^
Thanks,
Bill
On Wed, 2013-06-12 at 01:40 +0000, Eli Friedman wrote:
> Author: efriedma
> Date: Tue Jun 11 20:40:06 2013
> New Revision: 183821
>
> URL: http://llvm.org/viewvc/llvm-project?rev=183821&view=rev
> Log:
> Add support for complex compound assignments where the LHS is a scalar.
>
> Fixes <rdar://problem/11224126> and PR12790.
>
>
> Modified:
> cfe/trunk/lib/CodeGen/CGExprComplex.cpp
> cfe/trunk/lib/CodeGen/CGExprScalar.cpp
> cfe/trunk/lib/CodeGen/CodeGenFunction.h
> cfe/trunk/test/CodeGen/complex.c
> cfe/trunk/test/CodeGen/volatile-1.c
>
> Modified: cfe/trunk/lib/CodeGen/CGExprComplex.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprComplex.cpp?rev=183821&r1=183820&r2=183821&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGExprComplex.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGExprComplex.cpp Tue Jun 11 20:40:06 2013
> @@ -81,6 +81,9 @@ public:
> /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
> ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType,
> QualType DestType);
> + /// EmitComplexToComplexCast - Emit a cast from scalar value Val to DestType.
> + ComplexPairTy EmitScalarToComplexCast(llvm::Value *Val, QualType SrcType,
> + QualType DestType);
>
> //===--------------------------------------------------------------------===//
> // Visitor Methods
> @@ -215,7 +218,7 @@ public:
> LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E,
> ComplexPairTy (ComplexExprEmitter::*Func)
> (const BinOpInfo &),
> - ComplexPairTy &Val);
> + RValue &Val);
> ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E,
> ComplexPairTy (ComplexExprEmitter::*Func)
> (const BinOpInfo &));
> @@ -379,6 +382,17 @@ ComplexPairTy ComplexExprEmitter::EmitCo
> return Val;
> }
>
> +ComplexPairTy ComplexExprEmitter::EmitScalarToComplexCast(llvm::Value *Val,
> + QualType SrcType,
> + QualType DestType) {
> + // Convert the input element to the element type of the complex.
> + DestType = DestType->castAs<ComplexType>()->getElementType();
> + Val = CGF.EmitScalarConversion(Val, SrcType, DestType);
> +
> + // Return (realval, 0).
> + return ComplexPairTy(Val, llvm::Constant::getNullValue(Val->getType()));
> +}
> +
> ComplexPairTy ComplexExprEmitter::EmitCast(CastExpr::CastKind CK, Expr *Op,
> QualType DestTy) {
> switch (CK) {
> @@ -446,16 +460,9 @@ ComplexPairTy ComplexExprEmitter::EmitCa
> llvm_unreachable("invalid cast kind for complex value");
>
> case CK_FloatingRealToComplex:
> - case CK_IntegralRealToComplex: {
> - llvm::Value *Elt = CGF.EmitScalarExpr(Op);
> -
> - // Convert the input element to the element type of the complex.
> - DestTy = DestTy->castAs<ComplexType>()->getElementType();
> - Elt = CGF.EmitScalarConversion(Elt, Op->getType(), DestTy);
> -
> - // Return (realval, 0).
> - return ComplexPairTy(Elt, llvm::Constant::getNullValue(Elt->getType()));
> - }
> + case CK_IntegralRealToComplex:
> + return EmitScalarToComplexCast(CGF.EmitScalarExpr(Op),
> + Op->getType(), DestTy);
>
> case CK_FloatingComplexCast:
> case CK_FloatingComplexToIntegralComplex:
> @@ -610,7 +617,7 @@ ComplexExprEmitter::EmitBinOps(const Bin
> LValue ComplexExprEmitter::
> EmitCompoundAssignLValue(const CompoundAssignOperator *E,
> ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&),
> - ComplexPairTy &Val) {
> + RValue &Val) {
> TestAndClearIgnoreReal();
> TestAndClearIgnoreImag();
> QualType LHSTy = E->getLHS()->getType();
> @@ -630,20 +637,29 @@ EmitCompoundAssignLValue(const CompoundA
>
> LValue LHS = CGF.EmitLValue(E->getLHS());
>
> - // Load from the l-value.
> - ComplexPairTy LHSComplexPair = EmitLoadOfLValue(LHS);
> -
> - OpInfo.LHS = EmitComplexToComplexCast(LHSComplexPair, LHSTy, OpInfo.Ty);
> + // Load from the l-value and convert it.
> + if (LHSTy->isAnyComplexType()) {
> + ComplexPairTy LHSVal = EmitLoadOfLValue(LHS);
> + OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty);
> + } else {
> + llvm::Value *LHSVal = CGF.EmitLoadOfScalar(LHS);
> + OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty);
> + }
>
> // Expand the binary operator.
> ComplexPairTy Result = (this->*Func)(OpInfo);
>
> - // Truncate the result back to the LHS type.
> - Result = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy);
> - Val = Result;
> -
> - // Store the result value into the LHS lvalue.
> - EmitStoreOfComplex(Result, LHS, /*isInit*/ false);
> + // Truncate the result and store it into the LHS lvalue.
> + if (LHSTy->isAnyComplexType()) {
> + ComplexPairTy ResVal = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy);
> + EmitStoreOfComplex(ResVal, LHS, /*isInit*/ false);
> + Val = RValue::getComplex(ResVal);
> + } else {
> + llvm::Value *ResVal =
> + CGF.EmitComplexToScalarConversion(Result, OpInfo.Ty, LHSTy);
> + CGF.EmitStoreOfScalar(ResVal, LHS, /*isInit*/ false);
> + Val = RValue::get(ResVal);
> + }
>
> return LHS;
> }
> @@ -652,16 +668,16 @@ EmitCompoundAssignLValue(const CompoundA
> ComplexPairTy ComplexExprEmitter::
> EmitCompoundAssign(const CompoundAssignOperator *E,
> ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){
> - ComplexPairTy Val;
> + RValue Val;
> LValue LV = EmitCompoundAssignLValue(E, Func, Val);
>
> // The result of an assignment in C is the assigned r-value.
> if (!CGF.getLangOpts().CPlusPlus)
> - return Val;
> + return Val.getComplexVal();
>
> // If the lvalue is non-volatile, return the computed value of the assignment.
> if (!LV.isVolatileQualified())
> - return Val;
> + return Val.getComplexVal();
>
> return EmitLoadOfLValue(LV);
> }
> @@ -832,19 +848,33 @@ LValue CodeGenFunction::EmitComplexAssig
> return ComplexExprEmitter(*this).EmitBinAssignLValue(E, Val);
> }
>
> -LValue CodeGenFunction::
> -EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E) {
> - ComplexPairTy(ComplexExprEmitter::*Op)(const ComplexExprEmitter::BinOpInfo &);
> - switch (E->getOpcode()) {
> - case BO_MulAssign: Op = &ComplexExprEmitter::EmitBinMul; break;
> - case BO_DivAssign: Op = &ComplexExprEmitter::EmitBinDiv; break;
> - case BO_SubAssign: Op = &ComplexExprEmitter::EmitBinSub; break;
> - case BO_AddAssign: Op = &ComplexExprEmitter::EmitBinAdd; break;
> +typedef ComplexPairTy (ComplexExprEmitter::*CompoundFunc)(
> + const ComplexExprEmitter::BinOpInfo &);
>
> +static CompoundFunc getComplexOp(BinaryOperatorKind Op) {
> + switch (Op) {
> + case BO_MulAssign: return &ComplexExprEmitter::EmitBinMul;
> + case BO_DivAssign: return &ComplexExprEmitter::EmitBinDiv;
> + case BO_SubAssign: return &ComplexExprEmitter::EmitBinSub;
> + case BO_AddAssign: return &ComplexExprEmitter::EmitBinAdd;
> default:
> llvm_unreachable("unexpected complex compound assignment");
> }
> +}
>
> - ComplexPairTy Val; // ignored
> +LValue CodeGenFunction::
> +EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E) {
> + CompoundFunc Op = getComplexOp(E->getOpcode());
> + RValue Val;
> return ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val);
> }
> +
> +LValue CodeGenFunction::
> +EmitScalarCompooundAssignWithComplex(const CompoundAssignOperator *E,
> + llvm::Value *&Result) {
> + CompoundFunc Op = getComplexOp(E->getOpcode());
> + RValue Val;
> + LValue Ret = ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val);
> + Result = Val.getScalarVal();
> + return Ret;
> +}
>
> Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=183821&r1=183820&r2=183821&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Tue Jun 11 20:40:06 2013
> @@ -1931,15 +1931,8 @@ LValue ScalarExprEmitter::EmitCompoundAs
> QualType LHSTy = E->getLHS()->getType();
> BinOpInfo OpInfo;
>
> - if (E->getComputationResultType()->isAnyComplexType()) {
> - // This needs to go through the complex expression emitter, but it's a tad
> - // complicated to do that... I'm leaving it out for now. (Note that we do
> - // actually need the imaginary part of the RHS for multiplication and
> - // division.)
> - CGF.ErrorUnsupported(E, "complex compound assignment");
> - Result = llvm::UndefValue::get(CGF.ConvertType(E->getType()));
> - return LValue();
> - }
> + if (E->getComputationResultType()->isAnyComplexType())
> + return CGF.EmitScalarCompooundAssignWithComplex(E, Result);
>
> // Emit the RHS first. __block variables need to have the rhs evaluated
> // first, plus this should improve codegen a little.
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=183821&r1=183820&r2=183821&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Jun 11 20:40:06 2013
> @@ -1928,6 +1928,8 @@ public:
> /// Emit an l-value for an assignment (simple or compound) of complex type.
> LValue EmitComplexAssignmentLValue(const BinaryOperator *E);
> LValue EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E);
> + LValue EmitScalarCompooundAssignWithComplex(const CompoundAssignOperator *E,
> + llvm::Value *&Result);
>
> // Note: only available for agg return types
> LValue EmitBinaryOperatorLValue(const BinaryOperator *E);
>
> Modified: cfe/trunk/test/CodeGen/complex.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/complex.c?rev=183821&r1=183820&r2=183821&view=diff
> ==============================================================================
> --- cfe/trunk/test/CodeGen/complex.c (original)
> +++ cfe/trunk/test/CodeGen/complex.c Tue Jun 11 20:40:06 2013
> @@ -32,8 +32,7 @@ void test3() {
> double Gr = __real g1;
>
> cf += D;
> - // FIXME: Currently unsupported!
> - //D += cf;
> + D += cf;
> cf /= g1;
> g1 = g1 + D;
> g1 = D + g1;
> @@ -51,8 +50,7 @@ void test3int() {
> i = __real ci1;
>
> cs += i;
> - // FIXME: Currently unsupported!
> - //D += cf;
> + D += cf;
> cs /= ci1;
> ci1 = ci1 + i;
> ci1 = i + ci1;
>
> Modified: cfe/trunk/test/CodeGen/volatile-1.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/volatile-1.c?rev=183821&r1=183820&r2=183821&view=diff
> ==============================================================================
> --- cfe/trunk/test/CodeGen/volatile-1.c (original)
> +++ cfe/trunk/test/CodeGen/volatile-1.c Tue Jun 11 20:40:06 2013
> @@ -313,3 +313,15 @@ void test1() {
> (void) x;
> return x;
> }
> +
> +// CHECK: define i32 @test2()
> +int test2() {
> + // CHECK: load volatile i32*
> + // CHECK-NEXT: load volatile i32*
> + // CHECK-NEXT: load volatile i32*
> + // CHECK-NEXT: add i32
> + // CHECK-NEXT: add i32
> + // CHECK-NEXT: store volatile i32
> + // CHECK-NEXT: ret i32
> + return i += ci;
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
More information about the cfe-commits
mailing list