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