[llvm-commits] [dragonegg] r155583 - in /dragonegg/trunk: include/dragonegg/Internals.h src/Convert.cpp test/validator/fortran/2012-04-25-VecPermExpr.f90

Duncan Sands baldrick at free.fr
Wed Apr 25 13:42:50 PDT 2012


Author: baldrick
Date: Wed Apr 25 15:42:50 2012
New Revision: 155583

URL: http://llvm.org/viewvc/llvm-project?rev=155583&view=rev
Log:
Add support for VEC_PERM_EXPR (the new unified GCC shuffle in gcc-4.7), fixing
PR12610.

Added:
    dragonegg/trunk/test/validator/fortran/2012-04-25-VecPermExpr.f90
Modified:
    dragonegg/trunk/include/dragonegg/Internals.h
    dragonegg/trunk/src/Convert.cpp

Modified: dragonegg/trunk/include/dragonegg/Internals.h
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/include/dragonegg/Internals.h?rev=155583&r1=155582&r2=155583&view=diff
==============================================================================
--- dragonegg/trunk/include/dragonegg/Internals.h (original)
+++ dragonegg/trunk/include/dragonegg/Internals.h Wed Apr 25 15:42:50 2012
@@ -572,6 +572,9 @@
 
   // Ternary expressions.
   Value *EmitReg_CondExpr(tree_node *op0, tree_node *op1, tree_node *op2);
+#if (GCC_MINOR > 6)
+  Value *EmitReg_VEC_PERM_EXPR(tree_node *op0, tree_node *op1, tree_node *op2);
+#endif
 
   Value *EmitLoadOfLValue(tree_node *exp);
   Value *EmitOBJ_TYPE_REF(tree_node *exp);

Modified: dragonegg/trunk/src/Convert.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Convert.cpp?rev=155583&r1=155582&r2=155583&view=diff
==============================================================================
--- dragonegg/trunk/src/Convert.cpp (original)
+++ dragonegg/trunk/src/Convert.cpp Wed Apr 25 15:42:50 2012
@@ -7618,6 +7618,32 @@
   return Builder.CreateShuffleVector(LHS, RHS, ConstantVector::get(Mask));
 }
 
+#if (GCC_MINOR > 6)
+Value *TreeToLLVM::EmitReg_VEC_PERM_EXPR(tree op0, tree op1, tree op2) {
+  unsigned Length = (unsigned)TYPE_VECTOR_SUBPARTS(TREE_TYPE(op0));
+
+  // The vectors to shuffle.
+  Value *V0 = EmitRegister(op0);
+  Value *V1 = EmitRegister(op1);
+
+  // The shuffle mask.
+  Value *Mask = EmitRegister(op2);
+  assert(isa<Constant>(Mask) && "Only constant permutation masks supported!");
+
+  // Convert to a vector of i32, as required by the shufflevector instruction.
+  Type *MaskTy = VectorType::get(Builder.getInt32Ty(), Length);
+  tree mask_elt_type = TREE_TYPE(TREE_TYPE(op2));
+  Mask = Builder.CreateIntCast(Mask, MaskTy, !TYPE_UNSIGNED(mask_elt_type));
+
+  // The GCC semantics are that mask indices off the end are wrapped back into
+  // range, so reduce the mask modulo 2*Length.
+  assert(!(Length & (Length - 1)) && "Vector length not a power of two!");
+  Mask = Builder.CreateAnd(Mask, ConstantInt::get(Mask->getType(), 2*Length-1));
+
+  return Builder.CreateShuffleVector(V0, V1, Mask);
+}
+#endif
+
 Value *TreeToLLVM::EmitReg_VecUnpackHiExpr(tree type, tree op0) {
   // Eg: <2 x double> = VEC_UNPACK_HI_EXPR(<4 x float>)
   Value *Op = EmitRegister(op0);
@@ -8686,6 +8712,8 @@
   case COND_EXPR:
   case VEC_COND_EXPR:
     RHS = EmitReg_CondExpr(rhs1, rhs2, rhs3); break;
+  case VEC_PERM_EXPR:
+    RHS = EmitReg_VEC_PERM_EXPR(rhs1, rhs2, rhs3); break;
 #endif
   }
 

Added: dragonegg/trunk/test/validator/fortran/2012-04-25-VecPermExpr.f90
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/test/validator/fortran/2012-04-25-VecPermExpr.f90?rev=155583&view=auto
==============================================================================
--- dragonegg/trunk/test/validator/fortran/2012-04-25-VecPermExpr.f90 (added)
+++ dragonegg/trunk/test/validator/fortran/2012-04-25-VecPermExpr.f90 Wed Apr 25 15:42:50 2012
@@ -0,0 +1,37 @@
+! RUN: %dragonegg -S %s -O3 -fplugin-arg-dragonegg-enable-gcc-optzns
+! PR12610
+
+module solv_cap
+  integer, parameter, public :: dp = selected_real_kind(5)
+  real(kind=dp), private :: D1, D2
+  integer,       private, save :: Ng1=0, Ng2=0
+  integer,       private, pointer,     dimension(:,:)  :: Grid
+contains
+  subroutine Preco(X)
+    real(kind=dp), intent(in out), dimension(0:,0:)  :: X
+    complex(kind=dp), allocatable, dimension(:,:)    :: t
+    real(kind=dp)             :: K0, D
+    integer                   :: i, j, is, js
+    allocate( t(0:Ng1-1,0:Ng2-1) )
+    t = X
+    call Fourir2D(t, 1)
+    K0 = 0.15_dp
+    do j=0,Ng2-1
+      js = min(j, Ng2-j)
+      do i=0,Ng1-1
+        is = min(i, Ng1-i)
+        D = sqrt( (K0+is**2)/(D1*Ng1)**2 + (K0+js**2)/(D2*Ng2)**2 )
+        t(i,j) = t(i,j) * D
+      end do
+    end do
+    call Fourir2D(t, -1)
+    X = t(0:Ng1-1,0:Ng2-1)
+    where (Grid==0)
+      X = 0  
+    end where
+    deallocate( t )
+    return
+  end subroutine Preco
+end
+program capacitance
+end





More information about the llvm-commits mailing list