[cfe-commits] r74600 - /cfe/trunk/lib/AST/ExprConstant.cpp

Nate Begeman natebegeman at mac.com
Wed Jul 1 00:50:53 PDT 2009


Author: sampo
Date: Wed Jul  1 02:50:47 2009
New Revision: 74600

URL: http://llvm.org/viewvc/llvm-project?rev=74600&view=rev
Log:
Implement Eli's feedback for vecto constant expressions;

For ExtVectorType, initializer is splatted to all elements.
For VectorType, initializer is bitcast to vector type.

Verified that for VectorType, output is identical to gcc.

Modified:
    cfe/trunk/lib/AST/ExprConstant.cpp

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=74600&r1=74599&r2=74600&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Wed Jul  1 02:50:47 2009
@@ -485,6 +485,11 @@
 }
 
 APValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) {
+  const VectorType *VTy = E->getType()->getAsVectorType();
+  QualType EltTy = VTy->getElementType();
+  unsigned NElts = VTy->getNumElements();
+  unsigned EltWidth = Info.Ctx.getTypeSize(EltTy);
+  
   const Expr* SE = E->getSubExpr();
   QualType SETy = SE->getType();
   APValue Result = APValue();
@@ -501,13 +506,55 @@
     if (EvaluateFloat(SE, F, Info))
       Result = APValue(F);
   }
+  
+  if (!Result.isInt() && Result.isFloat())
+    return APValue();
 
-  if (Result.isInt() || Result.isFloat()) {
-    unsigned NumElts = E->getType()->getAsVectorType()->getNumElements();
-    llvm::SmallVector<APValue, 4> Elts(NumElts, Result);
-    Result = APValue(&Elts[0], Elts.size());
+  // For casts of a scalar to ExtVector, convert the scalar to the element type
+  // and splat it to all elements.
+  if (E->getType()->isExtVectorType()) {
+    if (EltTy->isIntegerType() && Result.isInt())
+      Result = APValue(HandleIntToIntCast(EltTy, SETy, Result.getInt(),
+                                          Info.Ctx));
+    else if (EltTy->isIntegerType())
+      Result = APValue(HandleFloatToIntCast(EltTy, SETy, Result.getFloat(),
+                                            Info.Ctx));
+    else if (EltTy->isRealFloatingType() && Result.isInt())
+      Result = APValue(HandleIntToFloatCast(EltTy, SETy, Result.getInt(),
+                                            Info.Ctx));
+    else if (EltTy->isRealFloatingType())
+      Result = APValue(HandleFloatToFloatCast(EltTy, SETy, Result.getFloat(),
+                                              Info.Ctx));
+    else
+      return APValue();
+
+    // Splat and create vector APValue.
+    llvm::SmallVector<APValue, 4> Elts(NElts, Result);
+    return APValue(&Elts[0], Elts.size());
   }
-  return Result;
+
+  // For casts of a scalar to regular gcc-style vector type, bitcast the scalar
+  // to the vector. To construct the APValue vector initializer, bitcast the
+  // initializing value to an APInt, and shift out the bits pertaining to each
+  // element.
+  APSInt Init;
+  Init = Result.isInt() ? Result.getInt() : Result.getFloat().bitcastToAPInt();
+  
+  llvm::SmallVector<APValue, 4> Elts;
+  for (unsigned i = 0; i != NElts; ++i) {
+    APSInt Tmp = Init;
+    Tmp.extOrTrunc(EltWidth);
+    
+    if (EltTy->isIntegerType())
+      Elts.push_back(APValue(Tmp));
+    else if (EltTy->isRealFloatingType())
+      Elts.push_back(APValue(APFloat(Tmp)));
+    else
+      return APValue();
+
+    Init >>= EltWidth;
+  }
+  return APValue(&Elts[0], Elts.size());
 }
 
 APValue 





More information about the cfe-commits mailing list