[cfe-commits] r39576 - in /cfe/cfe/trunk/CodeGen: CGExpr.cpp CodeGenFunction.h

clattner at cs.uiuc.edu clattner at cs.uiuc.edu
Wed Jul 11 09:45:48 PDT 2007


Author: clattner
Date: Wed Jul 11 11:45:47 2007
New Revision: 39576

URL: http://llvm.org/viewvc/llvm-project?rev=39576&view=rev
Log:
Implement EmitUsualArithmeticConversions, so we can add shorts to floats and
ints to long long etc.  For int to longlong, we now get:

        %tmp = load i64* %F             ; <i64> [#uses=1]
        %tmp1 = load i32* %D            ; <i32> [#uses=1]
        %promote = sext i32 %tmp1 to i64                ; <i64> [#uses=1]
        %tmp2 = add i64 %tmp, %promote          ; <i64> [#uses=0]

Modified:
    cfe/cfe/trunk/CodeGen/CGExpr.cpp
    cfe/cfe/trunk/CodeGen/CodeGenFunction.h

Modified: cfe/cfe/trunk/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CGExpr.cpp?rev=39576&r1=39575&r2=39576&view=diff

==============================================================================
--- cfe/cfe/trunk/CodeGen/CGExpr.cpp (original)
+++ cfe/cfe/trunk/CodeGen/CGExpr.cpp Wed Jul 11 11:45:47 2007
@@ -243,13 +243,109 @@
 //===--------------------------------------------------------------------===//
 
 // FIXME describe.
-void CodeGenFunction::EmitUsualArithmeticConversions(const BinaryOperator *E,
-                                                     ExprResult &LHS, 
-                                                     ExprResult &RHS) {
+QualType CodeGenFunction::
+EmitUsualArithmeticConversions(const BinaryOperator *E, ExprResult &LHS, 
+                               ExprResult &RHS) {
   QualType LHSType, RHSType;
   LHS = EmitExprWithUsualUnaryConversions(E->getLHS(), LHSType);
   RHS = EmitExprWithUsualUnaryConversions(E->getRHS(), RHSType);
 
+  // If both operands have the same source type, we're done already.
+  if (LHSType == RHSType) return LHSType;
+
+  // If either side is a non-arithmetic type (e.g. a pointer), we are done.
+  // The caller can deal with this (e.g. pointer + int).
+  if (!LHSType->isArithmeticType() || !RHSType->isArithmeticType())
+    return LHSType;
+
+  // At this point, we have two different arithmetic types. 
+  
+  // Handle complex types first (C99 6.3.1.8p1).
+  if (LHSType->isComplexType() || RHSType->isComplexType()) {
+    assert(0 && "FIXME: complex types unimp");
+#if 0
+    // if we have an integer operand, the result is the complex type.
+    if (rhs->isIntegerType())
+      return lhs;
+    if (lhs->isIntegerType())
+      return rhs;
+    return Context.maxComplexType(lhs, rhs);
+#endif
+  }
+  
+  // If neither operand is complex, they must be scalars.
+  llvm::Value *LHSV = LHS.getVal();
+  llvm::Value *RHSV = RHS.getVal();
+  
+  // If the LLVM types are already equal, then they only differed in sign, or it
+  // was something like char/signed char or double/long double.
+  if (LHSV->getType() == RHSV->getType())
+    return LHSType;
+  
+  // Now handle "real" floating types (i.e. float, double, long double).
+  if (LHSType->isRealFloatingType() || RHSType->isRealFloatingType()) {
+    // if we have an integer operand, the result is the real floating type, and
+    // the integer converts to FP.
+    if (RHSType->isIntegerType()) {
+      // Promote the RHS to an FP type of the LHS, with the sign following the
+      // RHS.
+      if (RHSType->isSignedIntegerType())
+        RHS = ExprResult::get(Builder.CreateSIToFP(RHSV, LHSV->getType(),
+                                                   "promote"));
+      else
+        RHS = ExprResult::get(Builder.CreateUIToFP(RHSV, LHSV->getType(),
+                                                   "promote"));
+      return LHSType;
+    }
+    
+    if (LHSType->isIntegerType()) {
+      // Promote the LHS to an FP type of the RHS, with the sign following the
+      // LHS.
+      if (LHSType->isSignedIntegerType())
+        LHS = ExprResult::get(Builder.CreateSIToFP(LHSV, RHSV->getType(),
+                                                   "promote"));
+      else
+        LHS = ExprResult::get(Builder.CreateUIToFP(LHSV, RHSV->getType(),
+                                                   "promote"));
+      return RHSType;
+    }
+    
+    // Otherwise, they are two FP types.  Promote the smaller operand to the
+    // bigger result.
+    QualType BiggerType = ASTContext::maxFloatingType(LHSType, RHSType);
+    
+    if (BiggerType == LHSType)
+      RHS = ExprResult::get(Builder.CreateFPExt(RHSV, LHSV->getType(),
+                                                "promote"));
+    else
+      LHS = ExprResult::get(Builder.CreateFPExt(LHSV, RHSV->getType(),
+                                                "promote"));
+    return BiggerType;
+  }
+  
+  // Finally, we have two integer types that are different according to C.  Do
+  // a sign or zero extension if needed.
+  
+  // Otherwise, one type is smaller than the other.  
+  QualType ResTy = ASTContext::maxIntegerType(LHSType, RHSType);
+  
+  if (LHSType == ResTy) {
+    if (RHSType->isSignedIntegerType())
+      RHS = ExprResult::get(Builder.CreateSExt(RHSV, LHSV->getType(),
+                                               "promote"));
+    else
+      RHS = ExprResult::get(Builder.CreateZExt(RHSV, LHSV->getType(),
+                                               "promote"));
+  } else {
+    assert(RHSType == ResTy && "Unknown conversion");
+    if (LHSType->isSignedIntegerType())
+      LHS = ExprResult::get(Builder.CreateSExt(LHSV, RHSV->getType(),
+                                               "promote"));
+    else
+      LHS = ExprResult::get(Builder.CreateZExt(LHSV, RHSV->getType(),
+                                               "promote"));
+  }  
+  return ResTy;
 }
 
 

Modified: cfe/cfe/trunk/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CodeGenFunction.h?rev=39576&r1=39575&r2=39576&view=diff

==============================================================================
--- cfe/cfe/trunk/CodeGen/CodeGenFunction.h (original)
+++ cfe/cfe/trunk/CodeGen/CodeGenFunction.h Wed Jul 11 11:45:47 2007
@@ -185,8 +185,8 @@
   ExprResult EmitIntegerLiteral(const IntegerLiteral *E);
   
   ExprResult EmitExprWithUsualUnaryConversions(const Expr *E, QualType &ResTy);
-  void EmitUsualArithmeticConversions(const BinaryOperator *E,
-                                      ExprResult &LHS, ExprResult &RHS);
+  QualType EmitUsualArithmeticConversions(const BinaryOperator *E,
+                                          ExprResult &LHS, ExprResult &RHS);
   
   // Unary Operators.
   ExprResult EmitUnaryOperator(const UnaryOperator *E);





More information about the cfe-commits mailing list