Bug 56873 - vector shift lowered to scalars
Summary: vector shift lowered to scalars
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Keywords: missed-optimization
Depends on:
Reported: 2013-04-08 11:39 UTC by Marc Glisse
Modified: 2013-09-14 09:50 UTC (History)
0 users

See Also:
Target: x86_64-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:


Note You need to log in before you can comment on or make changes to this bug.
Description Marc Glisse 2013-04-08 11:39:21 UTC
#define SIZE 32
typedef long long veci __attribute__((vector_size(SIZE)));

veci f(veci a, veci b){
  return a>>b;

Compiling this with -O3 -mxop, the vector lowering pass gives scalar operations. However, if SIZE is either 16 or 64, I get vector shifts of size 16.
Comment 1 Marc Glisse 2013-09-14 09:50:00 UTC
In the vector lowering pass, we only try to find a smaller vector that supports the operation if the larger vector is not a supported mode (never mind whether it supports the operation or not). The fact that the x86 backend says V4DI is supported seems strange to me, but let's continue. There is no reason why a target couldn't support some operations on V4DI and more on V2DI, so lowering still makes sense even from a supported mode. I quickly tried a hack in tree-vect-generic.c:

  /* For very wide vectors, try using a smaller vector mode.  */
  compute_type = type;
  if (op && (!VECTOR_MODE_P (TYPE_MODE (type))
             || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing))

But we then ICE in expr.c:

                /* Vector CONSTRUCTORs should only be built from smaller
                   vectors in the case of BLKmode vectors.  */
                gcc_assert (TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE);

And removing the assertion later fails with an unrecognizable insn:

(insn 18 17 19 2 (set (reg:V2DI 105)
        (vec_merge:V2DI (vec_duplicate:V2DI (reg:V2DI 102 [ D.2163 ]))
            (reg:V2DI 105)
            (const_int 1 [0x1]))) a.c:5 -1
a.c:6:1: internal compiler error: in extract_insn, at recog.c:2161

(looks like it got confused and lost the V4DI mode)

So this is not a simple tree-vect-generic issue :-(

I don't think we have any front-end or optimization producing a constructor v4di{v2di,v2di}, but that's more luck than anything else...