[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