http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59471
--- Comment #10 from Richard Biener <rguenth at gcc dot gnu.org> --- Testing Index: gimplify.c =================================================================== --- gimplify.c (revision 205891) +++ gimplify.c (working copy) @@ -7358,12 +7358,22 @@ gimplify_expr (tree *expr_p, gimple_seq TREE_TYPE (*expr_p)); break; + case VIEW_CONVERT_EXPR: + if (is_gimple_reg_type (TREE_TYPE (*expr_p)) + && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0)))) + { + ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, + post_p, is_gimple_val, fb_rvalue); + recalculate_side_effects (*expr_p); + break; + } + /* Fallthru. */ + case ARRAY_REF: case ARRAY_RANGE_REF: case REALPART_EXPR: case IMAGPART_EXPR: case COMPONENT_REF: - case VIEW_CONVERT_EXPR: ret = gimplify_compound_lval (expr_p, pre_p, post_p, fallback ? fallback : fb_rvalue); break; @@ -7709,10 +7719,17 @@ gimplify_expr (tree *expr_p, gimple_seq break; case BIT_FIELD_REF: - ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, - post_p, is_gimple_lvalue, fb_either); - recalculate_side_effects (*expr_p); - break; + { + if (is_gimple_reg_type (TREE_TYPE (*expr_p)) + && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0)))) + ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, + post_p, is_gimple_val, fb_rvalue); + else + ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, + post_p, is_gimple_lvalue, fb_either); + recalculate_side_effects (*expr_p); + break; + } case TARGET_MEM_REF: { code-generation for the testcase is awkward though: foo: .LFB0: .cfi_startproc movaps %xmm0, -24(%rsp) movq -24(%rsp), %rax movq %rax, -24(%rsp) movq -24(%rsp), %xmm0 ret not sure why RTL cannot recover here, we expand from foo (uint16x8_t x) { vector(2) long unsigned int _2; long unsigned int _3; uint8x8_t _4; <bb 2>: _2 = VIEW_CONVERT_EXPR<vector(2) long unsigned int>(x_5(D)); _3 = BIT_FIELD_REF <_2, 64, 0>; _4 = VIEW_CONVERT_EXPR<uint8x8_t>(_3); return _4; with forwprop we could re-write this into _4 = BIT_FIELD_REF <x_5(D), 64, 0>; as BIT_FIELD_REF is allowed to select uint8x8_t from uint16x8_t directly.