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

Alex Hill via gcc-help gcc-help@gcc.gnu.org
Tue Jun 11 08:32:00 GMT 2019




>Вторник, 11 июня 2019, 3:20 +05:00 от Jim Wilson <jimw@sifive.com>:
>
>On Sun, Jun 9, 2019 at 11:15 PM Alex Hill via gcc-help
>< gcc-help@gcc.gnu.org > wrote:
>> I found some decision, i used flags -fexceptions -fnon-call-exceptions and it emits max insn, now i try to understand why this happens.
>> Here is the max it emits:
>> (define_insn "smax<GPR:mode>3"
>>     [(set (match_operand:GPR 0 "register_operand" "=r")
>>         (smax:GPR (match_operand:GPR 1 "register_operand" " r")
>>         (match_operand:GPR 2 "register_operand" " r")))]
>> ""
>> "max\t%0,%1,%2"
>> [(set_attr "type" "move")
>> (set_attr "mode" "<MODE>")])
>
>There is some code in noce_try_minmax in ifcvt.c that will try to
>recognize an if statement in RTL that performs min/max and try to
>convert it to a direct min/max operation.  However, in general, you
>are more likely to get a min/max operation if you recognize it when
>parsing, and then carry it all of the way through the optimizer.  To
>make that work, you need min/max named patterns, that emit min/max
>operations in RTL.  Like what you have immediately above.  If trying
>to understand how this works, look at the debugging dumps you can get
>with -fdump-tree-all and -fdump-rtl-all when compiling a trivial
>testcase.  And maybe compare with another CPU target that already has
>working min/max support.
>
>Jim
What have i done for this moment:
I create some pattern:

(define_insn "<code><GPR:mode>3"
[(set (match_operand:GPR 0 "register_operand" "=r")
(any_maxmin:GPR (match_operand:GPR 1 "register_operand" " r")
(match_operand:GPR 2 "register_operand" " r")))]
""
"<maxmin>\t%0,%1,%2"
[(set_attr "type" "move")
(set_attr "mode" "<MODE>")])
It emit in case of indexed variables:

if ( A < C )
results[i] = A;
else if ( C < B )
results[i] = B;
else
results[i] = C; an assembler code:

.L15:
blt a4,a1,.L22
max 0(a2),a5,a1
ret
.L22:
sd a4,0(a2)
ret
.L21:
sd a5,0(a2)
ret

BUT! In case we using IF loop GCC wont emit minmax AGAIN!
for ( i = 1; i < (n-1); i++ ) {
A = input[i-1];
B = input[i];
C = input[i+1];
if ( A < B ) {
if ( B < C )
results[i] = B;
else if ( C < A )
results[i] = A;
else
results[i] = C;
}
else {
if ( A < C )
results[i] = A;
else if ( C < B )
results[i] = B;
else
results[i] = C;
}
}

Asembler code:

L3:
blt a4,a3,.L12
bgt a5,a3,.L11                 //instead of max
.L8:
sd a3,0(a2)
j .L5
.L11:
sd a5,0(a2)
j .L5 I supposed it happens because of this part:

(jump_insn 77 76 78 13 (set (pc)
(if_then_else (le (reg/v:DI 104 [ B ])
(reg/v:DI 105 [ C ]))
(label_ref 82)
(pc))) "./median/median1.c":58 -1
(int_list:REG_BR_PROB 5000 (nil))
-> 82)
(note 78 77 79 14 [bb 14] NOTE_INSN_BASIC_BLOCK)
(insn 79 78 80 14 (set (mem:DI (reg:DI 113 [ ivtmp.29 ]) [1 MEM[base: _39, offset: 0B]+0 S8 A64])       <----this part
(reg/v:DI 104 [ B ])) "./median/median1.c":59 -1
(nil))

what`s the difference between  

(reg:DI 113 [ ivtmp.29 ]) [1 MEM[base: _39, offset: 0B]+0 S8 A64])  

and (reg/f:DI 89 [ _48 ]) [1 *_48+0 S8 A64])

I can`t find meaning of ivtmp and MEM[base:_39,offset:0B]
Of course meaning in this case, i understand what mean "MEM" or "offset" or pointer.
In second string, same pointer + offset '*_48+0' statement.
Does anyone have any thoughts on this?

Sorry for my Engrish


Kind regards Alex Hill.


More information about the Gcc-help mailing list