On Mon, Aug 29, 2011 at 2:09 PM, Richard Guenther <richard.guent...@gmail.com> wrote: > On Mon, Aug 22, 2011 at 9:50 PM, Uros Bizjak <ubiz...@gmail.com> wrote: >> On Mon, Aug 22, 2011 at 5:34 PM, Richard Guenther >> <richard.guent...@gmail.com> wrote: >> >>>> In this case it is simple to analyse that a is a comparison, but you >>>> cannot embed the operations of a into VEC_COND_EXPR. >>> >>> Sure, but if the above is C source the frontend would generate >>> res = a != 0 ? v0 : v1; initially. An optimization pass could still >>> track this information and replace VEC_COND_EXPR <a != 0, v0, v1> >>> with VEC_COND_EXPR <a, v0, v1> (no existing one would track >>> vector contents though). >>> >>>> Ok, I am testing the patch that removes hooks. Could you push a little >>>> bit the backend-patterns business? >>> >>> Well, I suppose we're waiting for Uros here. I hadn't much luck with >>> fiddling with the mode-iterator stuff myself. >> >> It is not _that_ trivial change, since we have ix86_expand_fp_vcond >> and ix86_expand_int_vcond to merge. ATM, FP version deals with FP >> operands and vice versa. We have to merge them somehow and split out >> comparison part that handles FP as well as integer operands. >> >> I also don't know why vcond is not allowed to FAIL... probably >> middle-end should be enhanced for a fallback if some comparison isn't >> supported by optab. > > I wonder, if we make vcond being able to FAIL (well, it would fail for > invalid input only, like mismatching mode size), if patches along > > Index: gcc/config/i386/sse.md > =================================================================== > --- gcc/config/i386/sse.md (revision 178209) > +++ gcc/config/i386/sse.md (working copy) > @@ -1406,13 +1406,13 @@ (define_insn "<sse>_ucomi" > (set_attr "mode" "<MODE>")]) > > (define_expand "vcond<mode>" > - [(set (match_operand:VF 0 "register_operand" "") > - (if_then_else:VF > + [(set (match_operand 0 "register_operand" "") > + (if_then_else > (match_operator 3 "" > [(match_operand:VF 4 "nonimmediate_operand" "") > (match_operand:VF 5 "nonimmediate_operand" "")]) > - (match_operand:VF 1 "general_operand" "") > - (match_operand:VF 2 "general_operand" "")))] > + (match_operand 1 "general_operand" "") > + (match_operand 2 "general_operand" "")))] > "TARGET_SSE" > { > bool ok = ix86_expand_fp_vcond (operands); > > would be enough to make it accept V4SF < V4SF ? V4SI : V4SI with > target mode V4SI. The expander code doesn't seem to care about > the modes of op1/2 too much.
It at least "almost" works, apart from /space/rguenther/src/svn/trunk/gcc/testsuite/gcc.c-torture/execute/vector-compare-1.c:122:1: error: unrecognizable insn:^M (insn 1813 1812 1814 255 (set (reg:V4SI 1238)^M (lt:V4SI (reg:V4SF 1236)^M (reg:V4SF 619 [ D.3579 ]))) /space/rguenther/src/svn/trunk/gcc/testsuite/gcc.c-torture/execute/vector-compare-1.c:109 -1^M (nil))^M /space/rguenther/src/svn/trunk/gcc/testsuite/gcc.c-torture/execute/vector-compare-1.c:122:1: internal compiler error: in extract_insn, at recog.c:2115 I suppose the compare patterns need similar adjustments (though I couldn't find any SSE lt one, but that may be an artifact). Modeless operands are warned on though - do we have something better to simulate the effect? Like a mode mapper that does a 1:1 translation of an input mode from a mode iterator to another one? Can we use define_mode_attr for this? Like Index: config/i386/sse.md =================================================================== --- config/i386/sse.md (revision 178209) +++ config/i386/sse.md (working copy) @@ -161,6 +161,9 @@ (define_mode_attr avx_avx2 (V4SI "avx2") (V2DI "avx2") (V8SI "avx2") (V4DI "avx2")]) +(define_mode_attr cmpmode + [(V8SF "V8SI") (V4SF "V4SI") (V4DF "V4DI") (V2DF "V2DI")]) + ;; Mapping of logic-shift operators (define_code_iterator lshift [lshiftrt ashift]) @@ -1348,9 +1351,9 @@ (define_insn "<sse>_maskcmp<mode>3" (set_attr "mode" "<MODE>")]) (define_insn "<sse>_vmmaskcmp<mode>3" - [(set (match_operand:VF_128 0 "register_operand" "=x,x") - (vec_merge:VF_128 - (match_operator:VF_128 3 "sse_comparison_operator" + [(set (match_operand:<cmpmode> 0 "register_operand" "=x,x") + (vec_merge:<cmpmode> + (match_operator:<cmpmode> 3 "sse_comparison_operator" [(match_operand:VF_128 1 "register_operand" "0,x") (match_operand:VF_128 2 "nonimmediate_operand" "xm,xm")]) (match_dup 1) @@ -1406,13 +1409,13 @@ (define_insn "<sse>_ucomi" (set_attr "mode" "<MODE>")]) (define_expand "vcond<mode>" - [(set (match_operand:VF 0 "register_operand" "") - (if_then_else:VF - (match_operator 3 "" + [(set (match_operand 0 "register_operand" "") + (if_then_else + (match_operator:<cmpmode> 3 "" [(match_operand:VF 4 "nonimmediate_operand" "") (match_operand:VF 5 "nonimmediate_operand" "")]) - (match_operand:VF 1 "general_operand" "") - (match_operand:VF 2 "general_operand" "")))] + (match_operand 1 "general_operand" "") + (match_operand 2 "general_operand" "")))] "TARGET_SSE" { bool ok = ix86_expand_fp_vcond (operands); etc. That would still leave the result and 1st/2nd operand modes unspecified though (but we'd have the comparison result always an appropriate integer mode). Maybe (define_expand "vcond<mode>" [(set (match_operand:V_128 0 "register_operand" "") (if_then_else (match_operator:<cmpmode> 3 "" [(match_operand:VF_128 4 "nonimmediate_operand" "") (match_operand:VF_128 5 "nonimmediate_operand" "")]) (match_operand:V_128 1 "general_operand" "") (match_operand:V_128 2 "general_operand" "")))] "TARGET_SSE" { bool ok = ix86_expand_fp_vcond (operands); gcc_assert (ok); DONE; }) and a similar _256 patterns would work as well, but I guess it would lead to duplicate vcond<mode> gen_* functions. Richard. > Richard. > >> Uros. >> >