Disable (=&r,m,m) alternative for 32-bit targets. The combination of two memory operands (possibly with complex addressing mode), early clobbered output, frame pointer and PIC registers uses too many registers on a register constrained 32-bit target.
Also merge two similar patterns using DWIH mode iterator. PR target/111010 gcc/ChangeLog: * config/i386/i386.md (*concat<any_or_plus:mode><dwi>3_3): Merge pattern from *concatditi3_3 and *concatsidi3_3 using DWIH mode iterator. Disable (=&r,m,m) alternative for 32-bit targets. (*concat<any_or_plus:mode><dwi>3_4): Disable (=&r,m,m) alternative for 32-bit targets. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Also regtested by Rainer on i386-pc-solaris2.11 where the patch fixes the failure. (I didn't find a nice testcase, the test is very sensitive to perturbations in the code.) Uros.
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 108f4af8552..50794ed7bed 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -12435,17 +12435,16 @@ (define_insn_and_split "*concat<mode><dwi>3_2" DONE; }) -(define_insn_and_split "*concatditi3_3" - [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r,x") - (any_or_plus:TI - (ashift:TI - (zero_extend:TI - (match_operand:DI 1 "nonimmediate_operand" "r,m,r,m,x")) +(define_insn_and_split "*concat<mode><dwi>3_3" + [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r,x") + (any_or_plus:<DWI> + (ashift:<DWI> + (zero_extend:<DWI> + (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m,x")) (match_operand:QI 2 "const_int_operand")) - (zero_extend:TI - (match_operand:DI 3 "nonimmediate_operand" "r,r,m,m,0"))))] - "TARGET_64BIT - && INTVAL (operands[2]) == 64" + (zero_extend:<DWI> + (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m,0"))))] + "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT" "#" "&& reload_completed" [(const_int 0)] @@ -12456,28 +12455,10 @@ (define_insn_and_split "*concatditi3_3" emit_insn (gen_vec_concatv2di (tmp, operands[3], operands[1])); } else - split_double_concat (TImode, operands[0], operands[3], operands[1]); - DONE; -}) - -(define_insn_and_split "*concatsidi3_3" - [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,r,r,&r") - (any_or_plus:DI - (ashift:DI - (zero_extend:DI - (match_operand:SI 1 "nonimmediate_operand" "r,m,r,m")) - (match_operand:QI 2 "const_int_operand")) - (zero_extend:DI - (match_operand:SI 3 "nonimmediate_operand" "r,r,m,m"))))] - "!TARGET_64BIT - && INTVAL (operands[2]) == 32" - "#" - "&& reload_completed" - [(const_int 0)] -{ - split_double_concat (DImode, operands[0], operands[3], operands[1]); + split_double_concat (<DWI>mode, operands[0], operands[3], operands[1]); DONE; -}) +} + [(set_attr "isa" "*,*,*,x64,x64")]) (define_insn_and_split "*concat<mode><dwi>3_4" [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r") @@ -12495,7 +12476,8 @@ (define_insn_and_split "*concat<mode><dwi>3_4" { split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]); DONE; -}) +} + [(set_attr "isa" "*,*,*,x64")]) (define_insn_and_split "*concat<half><mode>3_5" [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")