On Fri, Jul 28, 2017 at 12:55 PM, Richard Sandiford
<richard.sandif...@linaro.org> wrote:
> Bin Cheng <bin.ch...@arm.com> writes:
>> Hi,
>> This simple patch fixes the ICE by adding LTGT in
>> vec_cmp<mode><v_cmp_result> pattern.
>> I also modified the original test case into a compilation one since
>> -fno-wrapping-math
>> should not be used in general.
>> Bootstrap and test on AArch64, test result check for x86_64.  Is it OK?
>> I would also need to
>> backport it to gcc-7-branch.
>>
>> Thanks,
>> bin
>> 2017-07-27  Bin Cheng  <bin.ch...@arm.com>
>>
>>       PR target/81228
>>       * config/aarch64/aarch64-simd.md (vec_cmp<mode><v_cmp_result>): Add
>>       LTGT.
>>
>> gcc/testsuite/ChangeLog
>> 2017-07-27  Bin Cheng  <bin.ch...@arm.com>
>>
>>       PR target/81228
>>       * gcc.dg/pr81228.c: New.
>>
>> diff --git a/gcc/config/aarch64/aarch64-simd.md 
>> b/gcc/config/aarch64/aarch64-simd.md
>> index 011fcec0..9cd67a2 100644
>> --- a/gcc/config/aarch64/aarch64-simd.md
>> +++ b/gcc/config/aarch64/aarch64-simd.md
>> @@ -2524,6 +2524,7 @@
>>      case EQ:
>>        comparison = gen_aarch64_cmeq<mode>;
>>        break;
>> +    case LTGT:
>>      case UNEQ:
>>      case ORDERED:
>>      case UNORDERED:
>> @@ -2571,6 +2572,7 @@
>>        emit_insn (comparison (operands[0], operands[2], operands[3]));
>>        break;
>>
>> +    case LTGT:
>>      case UNEQ:
>>        /* We first check (a > b ||  b > a) which is !UNEQ, inverting
>>        this result will then give us (a == b || a UNORDERED b).  */
>> @@ -2578,7 +2580,8 @@
>>                                        operands[2], operands[3]));
>>        emit_insn (gen_aarch64_cmgt<mode> (tmp, operands[3], operands[2]));
>>        emit_insn (gen_ior<v_cmp_result>3 (operands[0], operands[0], tmp));
>> -      emit_insn (gen_one_cmpl<v_cmp_result>2 (operands[0], operands[0]));
>> +      if (code == UNEQ)
>> +     emit_insn (gen_one_cmpl<v_cmp_result>2 (operands[0], operands[0]));
>>        break;
>
> AFAIK this is still a grey area, but I think (ltgt x y) is supposed to
> be a trapping operation, i.e. it's closer to (ior (lt x y) (gt x y))
> than (not (uneq x y)).  See e.g. the handling in may_trap_p_1, where
> LTGT is handled like LT and GT rather than like UNEQ.
>
> See also: https://gcc.gnu.org/ml/gcc-patches/2015-02/msg00583.html
Thanks for pointing me to this, I don't know anything about floating point here.
As for the change, the code now looks like:

    case LTGT:
    case UNEQ:
      /* We first check (a > b ||  b > a) which is !UNEQ, inverting
     this result will then give us (a == b || a UNORDERED b).  */
      emit_insn (gen_aarch64_cmgt<mode> (operands[0],
                     operands[2], operands[3]));
      emit_insn (gen_aarch64_cmgt<mode> (tmp, operands[3], operands[2]));
      emit_insn (gen_ior<v_cmp_result>3 (operands[0], operands[0], tmp));
      if (code == UNEQ)
    emit_insn (gen_one_cmpl<v_cmp_result>2 (operands[0], operands[0]));
      break;

So (a > b || b > a) is generated for LTGT which you suggested?  Here
we invert the result for UNEQ though.

Thanks,
bin
>
> Thanks,
> Richard

Reply via email to