On 14.12.2010 19:08, Douglas Gregor wrote:
On Nov 28, 2010, at 7:56 PM, Anton Yartsev wrote:

Support of ++/-- for AltiVec vectors according to "C/C++ Language Extensions for 
CBEA(Version 2.6)" section 10.3
A few comments.

Index: lib/CodeGen/CGExprScalar.cpp
===================================================================
--- lib/CodeGen/CGExprScalar.cpp        (revision 120239)
+++ lib/CodeGen/CGExprScalar.cpp        (working copy)
@@ -1257,10 +1257,11 @@
      // An interesting aspect of this is that increment is always true.
      // Decrement does not have this property.
      NextVal = llvm::ConstantInt::getTrue(VMContext);
-  } else if (isa<llvm::IntegerType>(InVal->getType())) {
+  } else if (isa<llvm::IntegerType>(InVal->getType()) ||
+             ValTy->isVectorType()&&  ValTy->hasIntegerRepresentation()) {
      NextVal = llvm::ConstantInt::get(InVal->getType(), AmountVal);
-
-    if (!ValTy->isSignedIntegerType())
+
+    if (!ValTy->hasSignedIntegerRepresentation())
        // Unsigned integer inc is always two's complement.
        NextVal = Builder.CreateAdd(InVal, NextVal, isInc ? "inc" : "dec");
      else {
@@ -1292,6 +1293,8 @@
        NextVal =
        llvm::ConstantFP::get(VMContext,
                              llvm::APFloat(static_cast<double>(AmountVal)));
+    else if (ValTy->isVectorType()&&  ValTy->hasFloatingRepresentation())
+      NextVal = llvm::ConstantFP::get(InVal->getType(), AmountVal);
      else {
        llvm::APFloat F(static_cast<float>(AmountVal));
        bool ignored;

This looks a bit tangled... please completely separate out the vector case, 
rather than lumping it in with the integer case.

Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp       (revision 120239)
+++ lib/Sema/SemaExpr.cpp       (working copy)
@@ -6931,6 +6931,8 @@
      if (PR.isInvalid()) return QualType();
      return CheckIncrementDecrementOperand(S, PR.take(), VK, OpLoc,
                                            isInc, isPrefix);
+  } else if (ResType->isVectorType()&&  S.getLangOptions().AltiVec) {
+    // OK! ( C/C++ Language Extensions for CBEA(Version 2.6) 10.3 )
    } else {
      S.Diag(OpLoc, diag::err_typecheck_illegal_increment_decrement)
        <<  ResType<<  int(isInc)<<  Op->getSourceRange();

Please check S.getLangOptions().AltiVec first, since the isVectorType() check 
is more expensive.

Could you add some test cases that ensure that ++ and -- on vectors work 
properly in C++? Things to consider:
        - Test that the result is an lvalue, such that you can assign to it,  
assign to its components, etc.
        - Test that ++/-- work in templates, both with an arbitrary type 'T' 
that gets instantiated to an AltiVec vector, and when we have an AltiVec vector 
of dependent size (e.g., the size is N, a non-type template parameter of type 
unsigned).

        - Doug
Here is the new patch. Took into account the comments, but have not got how to create AltiVec vector of dependent size. Did you mean creating gcc vector with the vector_size attribute?

--
Anton

Index: lib/CodeGen/CGExprScalar.cpp
===================================================================
--- lib/CodeGen/CGExprScalar.cpp        (revision 123621)
+++ lib/CodeGen/CGExprScalar.cpp        (working copy)
@@ -302,6 +302,11 @@
     return EmitScalarPrePostIncDec(E, LV, true, true);
   }
 
+  llvm::Value *EmitAddConsiderOverflowBehavior(const UnaryOperator *E,
+                                               llvm::Value *InVal,
+                                               llvm::Value *NextVal,
+                                               bool IsInc);
+
   llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
                                        bool isInc, bool isPre);
 
@@ -1222,6 +1227,31 @@
 
//===----------------------------------------------------------------------===//
 
 llvm::Value *ScalarExprEmitter::
+EmitAddConsiderOverflowBehavior(const UnaryOperator *E,
+                                llvm::Value *InVal,
+                                llvm::Value *NextVal, bool IsInc) {
+  switch (CGF.getContext().getLangOptions().getSignedOverflowBehavior()) {
+  case LangOptions::SOB_Undefined:
+    return Builder.CreateNSWAdd(InVal, NextVal, IsInc ? "inc" : "dec");
+    break;
+  case LangOptions::SOB_Defined:
+    return Builder.CreateAdd(InVal, NextVal, IsInc ? "inc" : "dec");
+    break;
+  case LangOptions::SOB_Trapping:
+    BinOpInfo BinOp;
+    BinOp.LHS = InVal;
+    BinOp.RHS = NextVal;
+    BinOp.Ty = E->getType();
+    BinOp.Opcode = BO_Add;
+    BinOp.E = E;
+    return EmitOverflowCheckedBinOp(BinOp);
+    break;
+  }
+  assert(false && "Unknown SignedOverflowBehaviorTy");
+  return 0;
+}
+
+llvm::Value *ScalarExprEmitter::
 EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
                         bool isInc, bool isPre) {
   
@@ -1270,31 +1300,26 @@
     // An interesting aspect of this is that increment is always true.
     // Decrement does not have this property.
     NextVal = llvm::ConstantInt::getTrue(VMContext);
+  } else if (ValTy->isVectorType()) {
+    if (ValTy->hasIntegerRepresentation()) {
+      NextVal = llvm::ConstantInt::get(InVal->getType(), AmountVal);
+
+      NextVal = ValTy->hasSignedIntegerRepresentation() ?
+                EmitAddConsiderOverflowBehavior(E, InVal, NextVal, isInc) :
+                Builder.CreateAdd(InVal, NextVal, isInc ? "inc" : "dec");
+    } else {
+      NextVal = Builder.CreateFAdd(
+                  InVal,
+                  llvm::ConstantFP::get(InVal->getType(), AmountVal),
+                  isInc ? "inc" : "dec");
+    }
   } else if (isa<llvm::IntegerType>(InVal->getType())) {
     NextVal = llvm::ConstantInt::get(InVal->getType(), AmountVal);
-    
-    if (!ValTy->isSignedIntegerType())
-      // Unsigned integer inc is always two's complement.
-      NextVal = Builder.CreateAdd(InVal, NextVal, isInc ? "inc" : "dec");
-    else {
-      switch (CGF.getContext().getLangOptions().getSignedOverflowBehavior()) {
-      case LangOptions::SOB_Undefined:
-        NextVal = Builder.CreateNSWAdd(InVal, NextVal, isInc ? "inc" : "dec");
-        break;
-      case LangOptions::SOB_Defined:
-        NextVal = Builder.CreateAdd(InVal, NextVal, isInc ? "inc" : "dec");
-        break;
-      case LangOptions::SOB_Trapping:
-        BinOpInfo BinOp;
-        BinOp.LHS = InVal;
-        BinOp.RHS = NextVal;
-        BinOp.Ty = E->getType();
-        BinOp.Opcode = BO_Add;
-        BinOp.E = E;
-        NextVal = EmitOverflowCheckedBinOp(BinOp);
-        break;
-      }
-    }
+
+    NextVal = ValTy->isSignedIntegerType() ?
+              EmitAddConsiderOverflowBehavior(E, InVal, NextVal, isInc) :
+              // Unsigned integer inc is always two's complement.
+              Builder.CreateAdd(InVal, NextVal, isInc ? "inc" : "dec");
   } else {
     // Add the inc/dec to the real part.
     if (InVal->getType()->isFloatTy())
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp       (revision 123621)
+++ lib/Sema/SemaExpr.cpp       (working copy)
@@ -7074,6 +7074,8 @@
     if (PR.isInvalid()) return QualType();
     return CheckIncrementDecrementOperand(S, PR.take(), VK, OpLoc,
                                           isInc, isPrefix);
+  } else if (S.getLangOptions().AltiVec && ResType->isVectorType()) {
+    // OK! ( C/C++ Language Extensions for CBEA(Version 2.6) 10.3 )
   } else {
     S.Diag(OpLoc, diag::err_typecheck_illegal_increment_decrement)
       << ResType << int(isInc) << Op->getSourceRange();
Index: test/CodeGen/builtins-ppc-altivec.c
===================================================================
--- test/CodeGen/builtins-ppc-altivec.c (revision 123621)
+++ test/CodeGen/builtins-ppc-altivec.c (working copy)
@@ -3113,3 +3113,14 @@
   res_i = (vf1 <= vf2);                    // CHECK: 
@llvm.ppc.altivec.vcmpgefp.p(i32 2
   res_i = (vf1 >= vf2);                    // CHECK: 
@llvm.ppc.altivec.vcmpgefp.p(i32 2
 }
+
+/* ------------------------------- increment/decrement: 
----------------------------- */
+// CHECK: define void @test8
+void test8() {
+  vector int vi;
+  vi++;                                    // CHECK: add nsw <4 x i32> {{.*}} 
<i32 1, i32 1, i32 1, i32 1>
+  vector unsigned int vui;
+  --vui;                                   // CHECK: add <4 x i32> {{.*}} <i32 
-1, i32 -1, i32 -1, i32 -1>
+  vector float vf;
+  vf++;                                    // CHECK: fadd <4 x float> {{.*}} 
<float 1.000000e+000, float 1.000000e+000, float 1.000000e+000, float 
1.000000e+000>
+}
Index: test/SemaCXX/altivec.cpp
===================================================================
--- test/SemaCXX/altivec.cpp    (revision 124026)
+++ test/SemaCXX/altivec.cpp    (working copy)
@@ -6,7 +6,7 @@
 {
 }
 
-void test()
+void test1()
 {
   V4i vGCC;
   vector int vAltiVec;
@@ -16,3 +16,24 @@
   bool res = vGCC > vAltiVec;
   vAltiVec = 0 ? vGCC : vGCC;
 }
+
+template<typename T>
+void template_f(T param) {
+  param++;
+}
+
+void test2()
+{
+  vector int vi;
+  ++vi;
+  vi++;
+  --vi;
+  vi--;
+  vector float vf;
+  vf++;
+
+  ++vi=vi;
+  vi++=vi;         // expected-error {{expression is not assignable}}
+  (++vi)[1]=1;
+  template_f(vi);
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to