>Вторник, 11 июня 2019, 3:20 +05:00 от Jim Wilson <jimw@xxxxxxxxxx>: > >On Sun, Jun 9, 2019 at 11:15 PM Alex Hill via gcc-help >< gcc-help@xxxxxxxxxxx > 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.