re PR c++/63419 (verify_gimple failed: "vector CONSTRUCTOR element is not a GIMPLE value")
2014-10-13 Richard Biener <rguenther@suse.de> PR tree-optimization/63419 * gimple-fold.h (gimple_convert): New function. * gimple-fold.c (gimple_convert): Likewise. * tree-ssa-pre.c (create_expression_by_pieces): Use gimple_convert to split out required conversions early. * g++.dg/torture/pr63419.C: New testcase. From-SVN: r216138
This commit is contained in:
parent
641123eb5e
commit
d4f5cd5e82
@ -1,3 +1,11 @@
|
||||
2014-10-13 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/63419
|
||||
* gimple-fold.h (gimple_convert): New function.
|
||||
* gimple-fold.c (gimple_convert): Likewise.
|
||||
* tree-ssa-pre.c (create_expression_by_pieces): Use gimple_convert
|
||||
to split out required conversions early.
|
||||
|
||||
2014-10-13 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
* rtlanal.c (generic_subrtx_iterator <T>::add_subrtxes_to_queue):
|
||||
|
@ -5295,3 +5295,20 @@ rewrite_to_defined_overflow (gimple stmt)
|
||||
|
||||
return stmts;
|
||||
}
|
||||
|
||||
/* Return OP converted to TYPE by emitting a conversion statement on SEQ
|
||||
if required using location LOC. Note that OP will be returned
|
||||
unmodified if GIMPLE does not require an explicit conversion between
|
||||
its type and TYPE. */
|
||||
|
||||
tree
|
||||
gimple_convert (gimple_seq *seq, location_t loc, tree type, tree op)
|
||||
{
|
||||
if (useless_type_conversion_p (type, TREE_TYPE (op)))
|
||||
return op;
|
||||
op = fold_convert_loc (loc, type, op);
|
||||
gimple_seq stmts = NULL;
|
||||
op = force_gimple_operand (op, &stmts, true, NULL_TREE);
|
||||
gimple_seq_add_seq_without_update (seq, stmts);
|
||||
return op;
|
||||
}
|
||||
|
@ -45,4 +45,11 @@ extern tree gimple_fold_indirect_ref (tree);
|
||||
extern bool arith_code_with_undefined_signed_overflow (tree_code);
|
||||
extern gimple_seq rewrite_to_defined_overflow (gimple);
|
||||
|
||||
extern tree gimple_convert (gimple_seq *, location_t, tree, tree);
|
||||
inline tree
|
||||
gimple_convert (gimple_seq *seq, tree type, tree op)
|
||||
{
|
||||
return gimple_convert (seq, UNKNOWN_LOCATION, type, op);
|
||||
}
|
||||
|
||||
#endif /* GCC_GIMPLE_FOLD_H */
|
||||
|
@ -1,3 +1,8 @@
|
||||
2014-10-13 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/63419
|
||||
* g++.dg/torture/pr63419.C: New testcase.
|
||||
|
||||
2014-10-12 Oleg Endo <olegendo@gcc.gnu.org>
|
||||
|
||||
PR target/59401
|
||||
|
225
gcc/testsuite/g++.dg/torture/pr63419.C
Normal file
225
gcc/testsuite/g++.dg/torture/pr63419.C
Normal file
@ -0,0 +1,225 @@
|
||||
// { dg-do compile }
|
||||
|
||||
typedef float __m128 __attribute__ ((__vector_size__ (16)));
|
||||
const int a = 0;
|
||||
enum
|
||||
{
|
||||
ReadOnlyAccessors
|
||||
};
|
||||
template <typename> struct traits;
|
||||
struct A
|
||||
{
|
||||
enum
|
||||
{
|
||||
value = 1
|
||||
};
|
||||
};
|
||||
template <typename> struct EigenBase;
|
||||
template <typename> class J;
|
||||
template <typename, int = A::value> class DenseCoeffsBase;
|
||||
template <typename, int, int, int = 0, int = 0, int = 0> class K;
|
||||
template <typename> class N;
|
||||
template <typename, typename> class CwiseUnaryOp;
|
||||
template <typename> class L;
|
||||
template <typename> class P;
|
||||
template <typename> struct B;
|
||||
template <typename> struct C;
|
||||
template <typename Derived> struct dense_xpr_base
|
||||
{
|
||||
typedef N<Derived> type;
|
||||
};
|
||||
template <typename Packet> void padd (Packet);
|
||||
template <> struct C<float>
|
||||
{
|
||||
typedef __m128 type;
|
||||
};
|
||||
struct D
|
||||
{
|
||||
void
|
||||
packetOp (C<float>::type)
|
||||
{
|
||||
__m128 b = { m_other };
|
||||
padd (b);
|
||||
}
|
||||
float m_other;
|
||||
};
|
||||
template <typename Derived>
|
||||
class DenseCoeffsBase<Derived, ReadOnlyAccessors> : public EigenBase<Derived>
|
||||
{
|
||||
public:
|
||||
typedef typename C<typename traits<Derived>::Scalar>::type PacketScalar;
|
||||
};
|
||||
template <typename Derived>
|
||||
class DenseCoeffsBase<Derived>
|
||||
: public DenseCoeffsBase<Derived, ReadOnlyAccessors>
|
||||
{
|
||||
public:
|
||||
template <typename OtherDerived, int, int LoadMode>
|
||||
void
|
||||
copyPacket (typename traits<Derived>::Index, J<OtherDerived> p2)
|
||||
{
|
||||
p2.derived ().template packet<LoadMode> (0);
|
||||
}
|
||||
};
|
||||
template <typename Derived> class J : public DenseCoeffsBase<Derived>
|
||||
{
|
||||
public:
|
||||
using DenseCoeffsBase<Derived>::derived;
|
||||
template <typename OtherDerived>
|
||||
Derived &lazyAssign (const J<OtherDerived> &);
|
||||
};
|
||||
template <typename Derived> class N : public J<Derived>
|
||||
{
|
||||
public:
|
||||
template <typename OtherDerived>
|
||||
typename B<OtherDerived>::Type operator*(N<OtherDerived>);
|
||||
L<Derived> array ();
|
||||
};
|
||||
template <typename Derived> struct EigenBase
|
||||
{
|
||||
Derived
|
||||
derived () const
|
||||
{
|
||||
return *static_cast<const Derived *> (this);
|
||||
}
|
||||
};
|
||||
template <typename Derived1, typename Derived2> struct F
|
||||
{
|
||||
static void
|
||||
run (Derived1 p1, Derived2 p2)
|
||||
{
|
||||
enum
|
||||
{
|
||||
srcAlignment
|
||||
};
|
||||
for (;;)
|
||||
p1.template copyPacket<Derived2, 0, srcAlignment> (0, p2);
|
||||
}
|
||||
};
|
||||
template <typename Derived>
|
||||
template <typename OtherDerived>
|
||||
Derived &
|
||||
J<Derived>::lazyAssign (const J<OtherDerived> &p1)
|
||||
{
|
||||
F<Derived, OtherDerived>::run (derived (), p1.derived ());
|
||||
}
|
||||
template <typename Derived, typename OtherDerived> struct G
|
||||
{
|
||||
static Derived
|
||||
run (Derived p1, OtherDerived p2)
|
||||
{
|
||||
p1.lazyAssign (p2);
|
||||
}
|
||||
};
|
||||
class H
|
||||
{
|
||||
public:
|
||||
H (int, int, int);
|
||||
};
|
||||
template <typename Derived> class M : public dense_xpr_base<Derived>::type
|
||||
{
|
||||
public:
|
||||
typedef typename traits<Derived>::Index Index;
|
||||
H m_storage;
|
||||
M (Index, Index, Index) : m_storage (0, 0, 0) {}
|
||||
template <typename OtherDerived>
|
||||
void
|
||||
_set_noalias (J<OtherDerived> p1)
|
||||
{
|
||||
G<Derived, OtherDerived>::run (this->derived (), p1.derived ());
|
||||
}
|
||||
};
|
||||
template <typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows,
|
||||
int _MaxCols>
|
||||
struct traits<K<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
|
||||
{
|
||||
typedef _Scalar Scalar;
|
||||
typedef int StorageKind;
|
||||
typedef int Index;
|
||||
};
|
||||
template <typename, int _Rows, int _Cols, int, int, int>
|
||||
class K : public M<K<float, _Rows, _Cols> >
|
||||
{
|
||||
public:
|
||||
typedef M<K> Base;
|
||||
typedef K Nested;
|
||||
template <typename T0, typename T1> K (T0, T1);
|
||||
template <typename OtherDerived> K (N<OtherDerived> p1) : Base (0, 0, 0)
|
||||
{
|
||||
Base::_set_noalias (p1);
|
||||
}
|
||||
};
|
||||
template <typename UnaryOp, typename XprType>
|
||||
struct traits<CwiseUnaryOp<UnaryOp, XprType> > : traits<XprType>
|
||||
{
|
||||
};
|
||||
template <typename, typename, typename> class I;
|
||||
template <typename, typename XprType>
|
||||
class CwiseUnaryOp
|
||||
: public I<D, XprType, typename traits<XprType>::StorageKind>
|
||||
{
|
||||
public:
|
||||
D
|
||||
functor ()
|
||||
{
|
||||
return m_functor;
|
||||
}
|
||||
typename XprType::Nested nestedExpression ();
|
||||
D m_functor;
|
||||
};
|
||||
template <typename UnaryOp, typename XprType>
|
||||
class I<UnaryOp, XprType, int>
|
||||
: public dense_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type
|
||||
{
|
||||
public:
|
||||
typedef CwiseUnaryOp<UnaryOp, XprType> Derived;
|
||||
typedef typename dense_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type Base;
|
||||
typedef Derived Nested;
|
||||
using Base::derived;
|
||||
template <int LoadMode> void packet (typename traits<Derived>::Index)
|
||||
{
|
||||
derived ().functor ().packetOp (
|
||||
derived ().nestedExpression ().template packet<LoadMode> (0));
|
||||
}
|
||||
};
|
||||
template <typename> struct B
|
||||
{
|
||||
typedef P<CwiseUnaryOp<D, L<K<float, 0, 1> > > > Type;
|
||||
};
|
||||
template <typename Derived> class O : public J<Derived>
|
||||
{
|
||||
public:
|
||||
P<Derived> matrix ();
|
||||
};
|
||||
template <typename ExpressionType>
|
||||
struct traits<L<ExpressionType> > : traits<typename ExpressionType::Nested>
|
||||
{
|
||||
};
|
||||
template <typename ExpressionType> class L : public O<L<ExpressionType> >
|
||||
{
|
||||
public:
|
||||
typedef L Nested;
|
||||
template <int>
|
||||
typename O<L>::PacketScalar packet (typename traits<L>::Index);
|
||||
};
|
||||
template <typename ExpressionType>
|
||||
struct traits<P<ExpressionType> > : traits<typename ExpressionType::Nested>
|
||||
{
|
||||
};
|
||||
template <typename ExpressionType> class P : public N<P<ExpressionType> >
|
||||
{
|
||||
public:
|
||||
N<P> Base;
|
||||
template <int LoadMode> void packet (typename traits<P>::Index)
|
||||
{
|
||||
m_expression.template packet<LoadMode> (0);
|
||||
}
|
||||
ExpressionType m_expression;
|
||||
};
|
||||
int
|
||||
main ()
|
||||
{
|
||||
K<float, 0, a> m (0, 0);
|
||||
K<float, 0, 1> c (0, 0);
|
||||
c = m.array ().matrix () * m;
|
||||
}
|
@ -2819,12 +2819,15 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
|
||||
if (nary->opcode == POINTER_PLUS_EXPR)
|
||||
{
|
||||
if (i == 0)
|
||||
genop[i] = fold_convert (nary->type, genop[i]);
|
||||
genop[i] = gimple_convert (&forced_stmts,
|
||||
nary->type, genop[i]);
|
||||
else if (i == 1)
|
||||
genop[i] = convert_to_ptrofftype (genop[i]);
|
||||
genop[i] = gimple_convert (&forced_stmts,
|
||||
sizetype, genop[i]);
|
||||
}
|
||||
else
|
||||
genop[i] = fold_convert (TREE_TYPE (nary->op[i]), genop[i]);
|
||||
genop[i] = gimple_convert (&forced_stmts,
|
||||
TREE_TYPE (nary->op[i]), genop[i]);
|
||||
}
|
||||
if (nary->opcode == CONSTRUCTOR)
|
||||
{
|
||||
@ -2866,8 +2869,10 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
|
||||
statements.
|
||||
We have to call unshare_expr because force_gimple_operand may
|
||||
modify the tree we pass to it. */
|
||||
folded = force_gimple_operand (unshare_expr (folded), &forced_stmts,
|
||||
gimple_seq tem = NULL;
|
||||
folded = force_gimple_operand (unshare_expr (folded), &tem,
|
||||
false, NULL);
|
||||
gimple_seq_add_seq_without_update (&forced_stmts, tem);
|
||||
|
||||
/* If we have any intermediate expressions to the value sets, add them
|
||||
to the value sets and chain them in the instruction stream. */
|
||||
|
Loading…
Reference in New Issue
Block a user