This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Vector Comparison patch
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
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.
>>
>