Patchwork Vector Comparison patch

login
register
mail settings
Submitter Richard Guenther
Date Aug. 29, 2011, 12:49 p.m.
Message ID <CAFiYyc3A4DQE5010OqMcR_f4ngr+T+4CYHoO1k1kWMzNs4zugw@mail.gmail.com>
Download mbox | patch
Permalink /patch/112037/
State New
Headers show

Comments

Richard Guenther - Aug. 29, 2011, 12:49 p.m.
On Mon, Aug 29, 2011 at 2:09 PM, Richard Guenther
<richard.guenther@gmail.com> wrote:
> On Mon, Aug 22, 2011 at 9:50 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
>> On Mon, Aug 22, 2011 at 5:34 PM, Richard Guenther
>> <richard.guenther@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



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.
>>
>

Patch

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);