Re[2]: GCC won`t emit my instriction

Alex Hill via gcc-help gcc-help@gcc.gnu.org
Fri Jun 7 05:37:00 GMT 2019




>Пятница,  7 июня 2019, 9:50 +05:00 от Jeff Law <law@redhat.com>:
>
>On 6/6/19 10:42 PM, Alex Hill via gcc-help wrote:
>> 
>> I need to reduce amount of branches in code. There is exist benchmark called median it have some code like:
>>     if ( A < B )
>>             return A = foo[i];
>>         else
>>             return B = foo[i];
>> I wrote a pattern in machine description file *.md to avoid branches:
>>     (define_insn "smin<GPR:mode>3"
>>       [
>>         (set 
>>           (match_operand:GPR 0 "register_operand" "=r")
>>             (if_then_else:GPR
>>           (lt:GPR 
>>             (match_operand:GPR 1 "register_operand" " r")
>>             (match_operand:GPR 2 "register_operand" " r"))
>>         (match_dup 1)
>>         (match_dup 2)))
>>       ]
>>       ""
>>       "min\t%0,%1,%2"
>>       [(set_attr "type" "move")
>>        (set_attr "mode" "<MODE>")]) 
>> It works in case of simple comparison:
>>     if ( A < B )
>>             return A ;
>>         else
>>             return B;
>> GCC emit:
>>     min a0,a0,a1    # 9 smindi3 [length = 4]
>>     ret # 21    simple_return   [length = 4]
>> But if i try same, but with indexed variable( array ): it won`t works:
>>     if ( A < B )
>>             return A = foo[i];
>>         else
>>             return B = foo[i];
>> GCC emit:
>>     blt a0,a1,.L5   # 11    *branch_orderdi [length = 4]
>>     sd  a1,8(a2)    # 18    *movdi_64bit/4  [length = 4]
>>     mv  a0,a1   # 8 *movdi_64bit/1  [length = 4]
>>     ret # 34    simple_return   [length = 4]
>>     .L5:
>>     sd  a0,8(a2)    # 13    *movdi_64bit/4  [length = 4]
>>     ret # 28    simple_return   [length = 4]
>> I need to GCC emit something like this:
>>     min a0,a0,a1    # 9 smindi3 [length = 4]
>>     sd  a0,8(a2)    # 18    *movdi_64bit/4  [length = 4]
>>     ret # 34    simple_return   [length = 4]
>> I appreciate any help, and i desperate to find a desicion, i tried to look into GIMPLE to change conditions of MIN_EXPR, but there is no(almost) any documentation, and sources are VERY puzzling((
>Rather than using a match_dup which requires the exact same register
>throughout the RTL pipeline, you might consider using a matching constraint.
>
>    (define_insn "smin<GPR:mode>3"
>      [
>        (set
>          (match_operand:GPR 0 "register_operand" "=r")
>            (if_then_else:GPR
>          (lt:GPR
>            (match_operand:GPR 1 "register_operand" " r")
>            (match_operand:GPR 2 "register_operand" " r"))
>        (match_operand:GPR 3 "register_operand" "1")
>        (match_operand:GPR 4 "register_operand" "2")))
>
>I would also strongly recommnend reviewing the various dump files to see
>if you're getting min/max as you leave gimple and if they're carried
>through the RTL pipeline.
>
>jeff
It won`t help of course, in GIMPLE direct comparisen gets

MIN_EXPR()

but indexed storing gets

long int _1;
<bb 2> [100.00%]:
if (A_3(D) < B_4(D))
goto <bb 3>; [46.00%]
else
goto <bb 4>; [54.00%]
<bb 3> [46.00%]:
MEM[(long int *)kekeke_5(D) + 8B] = A_3(D);
goto <bb 5>; [100.00%]
<bb 4> [54.00%]:
MEM[(long int *)kekeke_5(D) + 8B] = B_4(D);
<bb 5> [100.00%]:
# _1 = PHI <A_3(D)(3), B_4(D)(4)>
return _1;


Kind regards Alex Hill.


More information about the Gcc-help mailing list