Investigating PR target/86891 revealed a number of issues with the way the...
Investigating PR target/86891 revealed a number of issues with the way the AArch64 backend was handing overflow detection patterns. Firstly, expansion for signed and unsigned types is not the same as in one form the overflow is detected via the C flag and in the other it is done via the V flag in the PSR. Secondly, particular care has to be taken when describing overflow of signed types: the comparison has to be performed conceptually on a value that cannot overflow and compared to a value that might have overflowed. It became apparent that some of the patterns were simply unmatchable (they collapse to NEG in the RTL rather than subtracting from zero) and a number of patterns were overly restrictive in terms of the immediate constants that they supported. I've tried to address all of these issues as well. gcc: PR target/86891 * config/aarch64/aarch64.c (aarch64_expand_subvti): New parameter unsigned_p. Handle signed and unsigned overflow correction as required. * config/aarch64/aarch64-protos.h (aarch64_expand_subvti): Update prototype. * config/aarch64/aarch64.md (addv<mode>4): Use aarch64_plus_operand for operand 2. (add<mode>3_compareV_imm): Make this callable for expanding. (subv<GPI:mode>4): Use register_operand for operand 1. Use aarch64_plus_operand for operand 2. (subv<GPI:mode>_insn): New insn pattern. (subv<GPI:mode>_imm): Likewise. (negv<GPI:mode>3): New expand pattern. (negv<GPI:mode>_insn): New insn pattern. (negv<GPI:mode>_cmp_only): Likewise. (cmpv<GPI:mode>_insn): Likewise. (subvti4): Use register_operand for operand 1. Update call to aarch64_expand_subvti. (usubvti4): Likewise. (negvti3): New expand pattern. (negdi_carryout): New insn pattern. (negvdi_carryinV): New insn pattern. (sub<mode3>_compare1_imm): Delete named insn pattern, make anonymous version the named version. (peepholes to convert to sub<mode3>_compare1_imm): Adjust order of operands. (usub<GPI:mode>3_carryinC, usub<GPI:mode>3_carryinC_z1): New insn patterns. (usub<GPI:mode>3_carryinC_z2, usub<GPI:mode>3_carryinC): New insn patterns. (sub<mode>3_carryinCV, sub<mode>3_carryinCV_z1_z2): Delete. (sub<mode>3_carryinCV_z1, sub<mode>3_carryinCV_z2): Delete. (sub<mode>3_carryinCV): Delete. (sub<GPI:mode>3_carryinV): New expand pattern. sub<mode>3_carryinV, sub<mode>3_carryinV_z2): New insn patterns. testsuite: * gcc.target/aarch64/subs_compare_2.c: Make '#' immediate prefix optional in scan pattern. From-SVN: r267650
This commit is contained in:
parent
df35e0bde1
commit
a58fe3c5ca
6 changed files with 291 additions and 65 deletions
|
@ -1,3 +1,42 @@
|
|||
2019-01-07 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
PR target/86891
|
||||
* config/aarch64/aarch64.c (aarch64_expand_subvti): New parameter
|
||||
unsigned_p. Handle signed and unsigned overflow correction as
|
||||
required.
|
||||
* config/aarch64/aarch64-protos.h (aarch64_expand_subvti): Update
|
||||
prototype.
|
||||
* config/aarch64/aarch64.md (addv<mode>4): Use aarch64_plus_operand
|
||||
for operand 2.
|
||||
(add<mode>3_compareV_imm): Make this callable for expanding.
|
||||
(subv<GPI:mode>4): Use register_operand for operand 1. Use
|
||||
aarch64_plus_operand for operand 2.
|
||||
(subv<GPI:mode>_insn): New insn pattern.
|
||||
(subv<GPI:mode>_imm): Likewise.
|
||||
(negv<GPI:mode>3): New expand pattern.
|
||||
(negv<GPI:mode>_insn): New insn pattern.
|
||||
(negv<GPI:mode>_cmp_only): Likewise.
|
||||
(cmpv<GPI:mode>_insn): Likewise.
|
||||
(subvti4): Use register_operand for operand 1. Update call to
|
||||
aarch64_expand_subvti.
|
||||
(usubvti4): Likewise.
|
||||
(negvti3): New expand pattern.
|
||||
(negdi_carryout): New insn pattern.
|
||||
(negvdi_carryinV): New insn pattern.
|
||||
(sub<mode3>_compare1_imm): Delete named insn pattern, make anonymous
|
||||
version the named version.
|
||||
(peepholes to convert to sub<mode3>_compare1_imm): Adjust order of
|
||||
operands.
|
||||
(usub<GPI:mode>3_carryinC, usub<GPI:mode>3_carryinC_z1): New insn
|
||||
patterns.
|
||||
(usub<GPI:mode>3_carryinC_z2, usub<GPI:mode>3_carryinC): New insn
|
||||
patterns.
|
||||
(sub<mode>3_carryinCV, sub<mode>3_carryinCV_z1_z2): Delete.
|
||||
(sub<mode>3_carryinCV_z1, sub<mode>3_carryinCV_z2): Delete.
|
||||
(sub<mode>3_carryinCV): Delete.
|
||||
(sub<GPI:mode>3_carryinV): New expand pattern.
|
||||
sub<mode>3_carryinV, sub<mode>3_carryinV_z2): New insn patterns.
|
||||
|
||||
2019-01-07 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* tree-ssa-uncprop.c (ssa_equip_hash_traits): Remove in favor
|
||||
|
|
|
@ -530,7 +530,7 @@ void aarch64_subvti_scratch_regs (rtx, rtx, rtx *,
|
|||
rtx *, rtx *,
|
||||
rtx *, rtx *, rtx *);
|
||||
void aarch64_expand_subvti (rtx, rtx, rtx,
|
||||
rtx, rtx, rtx, rtx);
|
||||
rtx, rtx, rtx, rtx, bool);
|
||||
|
||||
|
||||
/* Initialize builtins for SIMD intrinsics. */
|
||||
|
|
|
@ -16668,32 +16668,38 @@ aarch64_subvti_scratch_regs (rtx op1, rtx op2, rtx *low_dest,
|
|||
LOW_IN2 represents the low half (DImode) of TImode operand 2
|
||||
HIGH_DEST represents the high half (DImode) of TImode operand 0
|
||||
HIGH_IN1 represents the high half (DImode) of TImode operand 1
|
||||
HIGH_IN2 represents the high half (DImode) of TImode operand 2. */
|
||||
|
||||
HIGH_IN2 represents the high half (DImode) of TImode operand 2
|
||||
UNSIGNED_P is true if the operation is being performed on unsigned
|
||||
values. */
|
||||
void
|
||||
aarch64_expand_subvti (rtx op0, rtx low_dest, rtx low_in1,
|
||||
rtx low_in2, rtx high_dest, rtx high_in1,
|
||||
rtx high_in2)
|
||||
rtx high_in2, bool unsigned_p)
|
||||
{
|
||||
if (low_in2 == const0_rtx)
|
||||
{
|
||||
low_dest = low_in1;
|
||||
emit_insn (gen_subdi3_compare1 (high_dest, high_in1,
|
||||
force_reg (DImode, high_in2)));
|
||||
high_in2 = force_reg (DImode, high_in2);
|
||||
if (unsigned_p)
|
||||
emit_insn (gen_subdi3_compare1 (high_dest, high_in1, high_in2));
|
||||
else
|
||||
emit_insn (gen_subvdi_insn (high_dest, high_in1, high_in2));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CONST_INT_P (low_in2))
|
||||
{
|
||||
low_in2 = force_reg (DImode, GEN_INT (-UINTVAL (low_in2)));
|
||||
high_in2 = force_reg (DImode, high_in2);
|
||||
emit_insn (gen_adddi3_compareC (low_dest, low_in1, low_in2));
|
||||
emit_insn (gen_subdi3_compare1_imm (low_dest, low_in1, low_in2,
|
||||
GEN_INT (-INTVAL (low_in2))));
|
||||
}
|
||||
else
|
||||
emit_insn (gen_subdi3_compare1 (low_dest, low_in1, low_in2));
|
||||
emit_insn (gen_subdi3_carryinCV (high_dest,
|
||||
force_reg (DImode, high_in1),
|
||||
high_in2));
|
||||
|
||||
if (unsigned_p)
|
||||
emit_insn (gen_usubdi3_carryinC (high_dest, high_in1, high_in2));
|
||||
else
|
||||
emit_insn (gen_subdi3_carryinV (high_dest, high_in1, high_in2));
|
||||
}
|
||||
|
||||
emit_move_insn (gen_lowpart (DImode, op0), low_dest);
|
||||
|
|
|
@ -1842,11 +1842,15 @@
|
|||
(define_expand "addv<mode>4"
|
||||
[(match_operand:GPI 0 "register_operand")
|
||||
(match_operand:GPI 1 "register_operand")
|
||||
(match_operand:GPI 2 "register_operand")
|
||||
(match_operand:GPI 2 "aarch64_plus_operand")
|
||||
(label_ref (match_operand 3 "" ""))]
|
||||
""
|
||||
{
|
||||
emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
|
||||
if (CONST_INT_P (operands[2]))
|
||||
emit_insn (gen_add<mode>3_compareV_imm (operands[0], operands[1],
|
||||
operands[2]));
|
||||
else
|
||||
emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
|
||||
aarch64_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
|
||||
|
||||
DONE;
|
||||
|
@ -2093,7 +2097,7 @@
|
|||
[(set_attr "type" "alus_sreg")]
|
||||
)
|
||||
|
||||
(define_insn "*add<mode>3_compareV_imm"
|
||||
(define_insn "add<mode>3_compareV_imm"
|
||||
[(set (reg:CC_V CC_REGNUM)
|
||||
(compare:CC_V
|
||||
(plus:<DWI>
|
||||
|
@ -2723,19 +2727,109 @@
|
|||
(set_attr "arch" "*,simd")]
|
||||
)
|
||||
|
||||
(define_expand "subv<mode>4"
|
||||
(define_expand "subv<GPI:mode>4"
|
||||
[(match_operand:GPI 0 "register_operand")
|
||||
(match_operand:GPI 1 "aarch64_reg_or_zero")
|
||||
(match_operand:GPI 2 "aarch64_reg_or_zero")
|
||||
(match_operand:GPI 1 "register_operand")
|
||||
(match_operand:GPI 2 "aarch64_plus_operand")
|
||||
(label_ref (match_operand 3 "" ""))]
|
||||
""
|
||||
{
|
||||
emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
|
||||
if (CONST_INT_P (operands[2]))
|
||||
emit_insn (gen_subv<mode>_imm (operands[0], operands[1], operands[2]));
|
||||
else
|
||||
emit_insn (gen_subv<mode>_insn (operands[0], operands[1], operands[2]));
|
||||
aarch64_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
|
||||
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn "subv<GPI:mode>_insn"
|
||||
[(set (reg:CC_V CC_REGNUM)
|
||||
(compare:CC_V
|
||||
(sign_extend:<DWI>
|
||||
(minus:GPI
|
||||
(match_operand:GPI 1 "register_operand" "rk")
|
||||
(match_operand:GPI 2 "register_operand" "r")))
|
||||
(minus:<DWI> (sign_extend:<DWI> (match_dup 1))
|
||||
(sign_extend:<DWI> (match_dup 2)))))
|
||||
(set (match_operand:GPI 0 "register_operand" "=r")
|
||||
(minus:GPI (match_dup 1) (match_dup 2)))]
|
||||
""
|
||||
"subs\\t%<w>0, %<w>1, %<w>2"
|
||||
[(set_attr "type" "alus_sreg")]
|
||||
)
|
||||
|
||||
(define_insn "subv<GPI:mode>_imm"
|
||||
[(set (reg:CC_V CC_REGNUM)
|
||||
(compare:CC_V
|
||||
(sign_extend:<DWI>
|
||||
(minus:GPI
|
||||
(match_operand:GPI 1 "register_operand" "rk,rk")
|
||||
(match_operand:GPI 2 "aarch64_plus_immediate" "I,J")))
|
||||
(minus:<DWI> (sign_extend:<DWI> (match_dup 1))
|
||||
(match_dup 2))))
|
||||
(set (match_operand:GPI 0 "register_operand" "=r,r")
|
||||
(minus:GPI (match_dup 1) (match_dup 2)))]
|
||||
""
|
||||
"@
|
||||
subs\\t%<w>0, %<w>1, %2
|
||||
adds\\t%<w>0, %<w>1, #%n2"
|
||||
[(set_attr "type" "alus_sreg")]
|
||||
)
|
||||
|
||||
(define_expand "negv<GPI:mode>3"
|
||||
[(match_operand:GPI 0 "register_operand")
|
||||
(match_operand:GPI 1 "register_operand")
|
||||
(label_ref (match_operand 2 "" ""))]
|
||||
""
|
||||
{
|
||||
emit_insn (gen_negv<mode>_insn (operands[0], operands[1]));
|
||||
aarch64_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
|
||||
|
||||
DONE;
|
||||
}
|
||||
)
|
||||
|
||||
(define_insn "negv<GPI:mode>_insn"
|
||||
[(set (reg:CC_V CC_REGNUM)
|
||||
(compare:CC_V
|
||||
(sign_extend:<DWI>
|
||||
(neg:GPI (match_operand:GPI 1 "register_operand" "r")))
|
||||
(neg:<DWI> (sign_extend:<DWI> (match_dup 1)))))
|
||||
(set (match_operand:GPI 0 "register_operand" "=r")
|
||||
(neg:GPI (match_dup 1)))]
|
||||
""
|
||||
"negs\\t%<w>0, %<w>1"
|
||||
[(set_attr "type" "alus_sreg")]
|
||||
)
|
||||
|
||||
(define_insn "negv<GPI:mode>_cmp_only"
|
||||
[(set (reg:CC_V CC_REGNUM)
|
||||
(compare:CC_V
|
||||
(sign_extend:<DWI>
|
||||
(neg:GPI (match_operand:GPI 0 "register_operand" "r")))
|
||||
(neg:<DWI> (sign_extend:<DWI> (match_dup 0)))))]
|
||||
""
|
||||
"negs\\t%<w>zr, %<w>0"
|
||||
[(set_attr "type" "alus_sreg")]
|
||||
)
|
||||
|
||||
(define_insn "*cmpv<GPI:mode>_insn"
|
||||
[(set (reg:CC_V CC_REGNUM)
|
||||
(compare:CC_V
|
||||
(sign_extend:<DWI>
|
||||
(minus:GPI (match_operand:GPI 0 "register_operand" "r,r,r")
|
||||
(match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))
|
||||
(minus:<DWI> (sign_extend:<DWI> (match_dup 0))
|
||||
(sign_extend:<DWI> (match_dup 1)))))]
|
||||
""
|
||||
"@
|
||||
cmp\\t%<w>0, %<w>1
|
||||
cmp\\t%<w>0, %1
|
||||
cmp\\t%<w>0, #%n1"
|
||||
[(set_attr "type" "alus_sreg")]
|
||||
)
|
||||
|
||||
(define_expand "usubv<mode>4"
|
||||
[(match_operand:GPI 0 "register_operand")
|
||||
(match_operand:GPI 1 "aarch64_reg_or_zero")
|
||||
|
@ -2771,7 +2865,7 @@
|
|||
|
||||
(define_expand "subvti4"
|
||||
[(match_operand:TI 0 "register_operand")
|
||||
(match_operand:TI 1 "aarch64_reg_or_zero")
|
||||
(match_operand:TI 1 "register_operand")
|
||||
(match_operand:TI 2 "aarch64_reg_or_imm")
|
||||
(label_ref (match_operand 3 "" ""))]
|
||||
""
|
||||
|
@ -2782,7 +2876,7 @@
|
|||
&low_dest, &op1_low, &op2_low,
|
||||
&high_dest, &op1_high, &op2_high);
|
||||
aarch64_expand_subvti (operands[0], low_dest, op1_low, op2_low,
|
||||
high_dest, op1_high, op2_high);
|
||||
high_dest, op1_high, op2_high, false);
|
||||
|
||||
aarch64_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
|
||||
DONE;
|
||||
|
@ -2790,7 +2884,7 @@
|
|||
|
||||
(define_expand "usubvti4"
|
||||
[(match_operand:TI 0 "register_operand")
|
||||
(match_operand:TI 1 "aarch64_reg_or_zero")
|
||||
(match_operand:TI 1 "register_operand")
|
||||
(match_operand:TI 2 "aarch64_reg_or_imm")
|
||||
(label_ref (match_operand 3 "" ""))]
|
||||
""
|
||||
|
@ -2801,12 +2895,56 @@
|
|||
&low_dest, &op1_low, &op2_low,
|
||||
&high_dest, &op1_high, &op2_high);
|
||||
aarch64_expand_subvti (operands[0], low_dest, op1_low, op2_low,
|
||||
high_dest, op1_high, op2_high);
|
||||
high_dest, op1_high, op2_high, true);
|
||||
|
||||
aarch64_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "negvti3"
|
||||
[(match_operand:TI 0 "register_operand")
|
||||
(match_operand:TI 1 "register_operand")
|
||||
(label_ref (match_operand 2 "" ""))]
|
||||
""
|
||||
{
|
||||
emit_insn (gen_negdi_carryout (gen_lowpart (DImode, operands[0]),
|
||||
gen_lowpart (DImode, operands[1])));
|
||||
emit_insn (gen_negvdi_carryinV (gen_highpart (DImode, operands[0]),
|
||||
gen_highpart (DImode, operands[1])));
|
||||
aarch64_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
|
||||
|
||||
DONE;
|
||||
}
|
||||
)
|
||||
|
||||
(define_insn "negdi_carryout"
|
||||
[(set (reg:CC CC_REGNUM)
|
||||
(compare:CC
|
||||
(const_int 0) (match_operand:DI 1 "register_operand" "r")))
|
||||
(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(neg:DI (match_dup 1)))]
|
||||
""
|
||||
"negs\\t%0, %1"
|
||||
[(set_attr "type" "alus_sreg")]
|
||||
)
|
||||
|
||||
(define_insn "negvdi_carryinV"
|
||||
[(set (reg:CC_V CC_REGNUM)
|
||||
(compare:CC_V
|
||||
(neg:TI (plus:TI
|
||||
(ltu:TI (reg:CC CC_REGNUM) (const_int 0))
|
||||
(sign_extend:TI (match_operand:DI 1 "register_operand" "r"))))
|
||||
(sign_extend:TI
|
||||
(neg:DI (plus:DI (ltu:DI (reg:CC CC_REGNUM) (const_int 0))
|
||||
(match_dup 1))))))
|
||||
(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(neg:DI (plus:DI (ltu:DI (reg:CC CC_REGNUM) (const_int 0))
|
||||
(match_dup 1))))]
|
||||
""
|
||||
"ngcs\\t%0, %1"
|
||||
[(set_attr "type" "alus_sreg")]
|
||||
)
|
||||
|
||||
(define_insn "*sub<mode>3_compare0"
|
||||
[(set (reg:CC_NZ CC_REGNUM)
|
||||
(compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
|
||||
|
@ -2832,7 +2970,7 @@
|
|||
[(set_attr "type" "alus_sreg")]
|
||||
)
|
||||
|
||||
(define_insn "*sub<mode>3_compare1_imm"
|
||||
(define_insn "sub<mode>3_compare1_imm"
|
||||
[(set (reg:CC CC_REGNUM)
|
||||
(compare:CC
|
||||
(match_operand:GPI 1 "aarch64_reg_or_zero" "rZ,rZ")
|
||||
|
@ -2843,8 +2981,8 @@
|
|||
(match_operand:GPI 3 "aarch64_plus_immediate" "J,I")))]
|
||||
"UINTVAL (operands[2]) == -UINTVAL (operands[3])"
|
||||
"@
|
||||
subs\\t%<w>0, %<w>1, #%n3
|
||||
adds\\t%<w>0, %<w>1, %3"
|
||||
subs\\t%<w>0, %<w>1, %2
|
||||
adds\\t%<w>0, %<w>1, #%n2"
|
||||
[(set_attr "type" "alus_imm")]
|
||||
)
|
||||
|
||||
|
@ -2860,19 +2998,6 @@
|
|||
[(set_attr "type" "alus_sreg")]
|
||||
)
|
||||
|
||||
(define_insn "sub<mode>3_compare1_imm"
|
||||
[(set (reg:CC CC_REGNUM)
|
||||
(compare:CC
|
||||
(match_operand:GPI 1 "register_operand" "r")
|
||||
(match_operand:GPI 3 "const_int_operand" "n")))
|
||||
(set (match_operand:GPI 0 "register_operand" "=r")
|
||||
(plus:GPI (match_dup 1)
|
||||
(match_operand:GPI 2 "aarch64_sub_immediate" "J")))]
|
||||
"INTVAL (operands[3]) == -INTVAL (operands[2])"
|
||||
"subs\\t%<w>0, %<w>1, #%n2"
|
||||
[(set_attr "type" "alus_sreg")]
|
||||
)
|
||||
|
||||
(define_peephole2
|
||||
[(set (match_operand:GPI 0 "register_operand")
|
||||
(minus:GPI (match_operand:GPI 1 "aarch64_reg_or_zero")
|
||||
|
@ -2914,7 +3039,7 @@
|
|||
(define_peephole2
|
||||
[(set (match_operand:GPI 0 "register_operand")
|
||||
(plus:GPI (match_operand:GPI 1 "register_operand")
|
||||
(match_operand:GPI 2 "aarch64_sub_immediate")))
|
||||
(match_operand:GPI 2 "aarch64_plus_immediate")))
|
||||
(set (reg:CC CC_REGNUM)
|
||||
(compare:CC
|
||||
(match_dup 1)
|
||||
|
@ -2924,7 +3049,7 @@
|
|||
[(const_int 0)]
|
||||
{
|
||||
emit_insn (gen_sub<mode>3_compare1_imm (operands[0], operands[1],
|
||||
operands[2], operands[3]));
|
||||
operands[3], operands[2]));
|
||||
DONE;
|
||||
}
|
||||
)
|
||||
|
@ -2939,12 +3064,12 @@
|
|||
(match_operand:GPI 3 "const_int_operand")))
|
||||
(set (match_operand:GPI 0 "register_operand")
|
||||
(plus:GPI (match_dup 1)
|
||||
(match_operand:GPI 2 "aarch64_sub_immediate")))]
|
||||
(match_operand:GPI 2 "aarch64_plus_immediate")))]
|
||||
"INTVAL (operands[3]) == -INTVAL (operands[2])"
|
||||
[(const_int 0)]
|
||||
{
|
||||
emit_insn (gen_sub<mode>3_compare1_imm (operands[0], operands[1],
|
||||
operands[2], operands[3]));
|
||||
operands[3], operands[2]));
|
||||
DONE;
|
||||
}
|
||||
)
|
||||
|
@ -3164,14 +3289,14 @@
|
|||
[(set_attr "type" "adc_reg")]
|
||||
)
|
||||
|
||||
(define_expand "sub<mode>3_carryinCV"
|
||||
(define_expand "usub<GPI:mode>3_carryinC"
|
||||
[(parallel
|
||||
[(set (reg:CC CC_REGNUM)
|
||||
(compare:CC
|
||||
(sign_extend:<DWI>
|
||||
(zero_extend:<DWI>
|
||||
(match_operand:GPI 1 "aarch64_reg_or_zero" ""))
|
||||
(plus:<DWI>
|
||||
(sign_extend:<DWI>
|
||||
(zero_extend:<DWI>
|
||||
(match_operand:GPI 2 "register_operand" ""))
|
||||
(ltu:<DWI> (reg:CC CC_REGNUM) (const_int 0)))))
|
||||
(set (match_operand:GPI 0 "register_operand" "")
|
||||
|
@ -3181,24 +3306,12 @@
|
|||
""
|
||||
)
|
||||
|
||||
(define_insn "*sub<mode>3_carryinCV_z1_z2"
|
||||
[(set (reg:CC CC_REGNUM)
|
||||
(compare:CC
|
||||
(const_int 0)
|
||||
(match_operand:<DWI> 2 "aarch64_borrow_operation" "")))
|
||||
(set (match_operand:GPI 0 "register_operand" "=r")
|
||||
(neg:GPI (match_operand:GPI 1 "aarch64_borrow_operation" "")))]
|
||||
""
|
||||
"sbcs\\t%<w>0, <w>zr, <w>zr"
|
||||
[(set_attr "type" "adc_reg")]
|
||||
)
|
||||
|
||||
(define_insn "*sub<mode>3_carryinCV_z1"
|
||||
(define_insn "*usub<GPI:mode>3_carryinC_z1"
|
||||
[(set (reg:CC CC_REGNUM)
|
||||
(compare:CC
|
||||
(const_int 0)
|
||||
(plus:<DWI>
|
||||
(sign_extend:<DWI>
|
||||
(zero_extend:<DWI>
|
||||
(match_operand:GPI 1 "register_operand" "r"))
|
||||
(match_operand:<DWI> 2 "aarch64_borrow_operation" ""))))
|
||||
(set (match_operand:GPI 0 "register_operand" "=r")
|
||||
|
@ -3210,10 +3323,10 @@
|
|||
[(set_attr "type" "adc_reg")]
|
||||
)
|
||||
|
||||
(define_insn "*sub<mode>3_carryinCV_z2"
|
||||
(define_insn "*usub<GPI:mode>3_carryinC_z2"
|
||||
[(set (reg:CC CC_REGNUM)
|
||||
(compare:CC
|
||||
(sign_extend:<DWI>
|
||||
(zero_extend:<DWI>
|
||||
(match_operand:GPI 1 "register_operand" "r"))
|
||||
(match_operand:<DWI> 2 "aarch64_borrow_operation" "")))
|
||||
(set (match_operand:GPI 0 "register_operand" "=r")
|
||||
|
@ -3225,13 +3338,13 @@
|
|||
[(set_attr "type" "adc_reg")]
|
||||
)
|
||||
|
||||
(define_insn "*sub<mode>3_carryinCV"
|
||||
(define_insn "*usub<GPI:mode>3_carryinC"
|
||||
[(set (reg:CC CC_REGNUM)
|
||||
(compare:CC
|
||||
(sign_extend:<DWI>
|
||||
(zero_extend:<DWI>
|
||||
(match_operand:GPI 1 "register_operand" "r"))
|
||||
(plus:<DWI>
|
||||
(sign_extend:<DWI>
|
||||
(zero_extend:<DWI>
|
||||
(match_operand:GPI 2 "register_operand" "r"))
|
||||
(match_operand:<DWI> 3 "aarch64_borrow_operation" ""))))
|
||||
(set (match_operand:GPI 0 "register_operand" "=r")
|
||||
|
@ -3243,6 +3356,69 @@
|
|||
[(set_attr "type" "adc_reg")]
|
||||
)
|
||||
|
||||
(define_expand "sub<GPI:mode>3_carryinV"
|
||||
[(parallel
|
||||
[(set (reg:CC_V CC_REGNUM)
|
||||
(compare:CC_V
|
||||
(minus:<DWI>
|
||||
(sign_extend:<DWI>
|
||||
(match_operand:GPI 1 "aarch64_reg_or_zero" ""))
|
||||
(plus:<DWI>
|
||||
(sign_extend:<DWI>
|
||||
(match_operand:GPI 2 "register_operand" ""))
|
||||
(ltu:<DWI> (reg:CC CC_REGNUM) (const_int 0))))
|
||||
(sign_extend:<DWI>
|
||||
(minus:GPI (match_dup 1)
|
||||
(plus:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0))
|
||||
(match_dup 2))))))
|
||||
(set (match_operand:GPI 0 "register_operand" "")
|
||||
(minus:GPI
|
||||
(minus:GPI (match_dup 1) (match_dup 2))
|
||||
(ltu:GPI (reg:CC CC_REGNUM) (const_int 0))))])]
|
||||
""
|
||||
)
|
||||
|
||||
(define_insn "*sub<mode>3_carryinV_z2"
|
||||
[(set (reg:CC_V CC_REGNUM)
|
||||
(compare:CC_V
|
||||
(minus:<DWI>
|
||||
(sign_extend:<DWI> (match_operand:GPI 1 "register_operand" "r"))
|
||||
(match_operand:<DWI> 2 "aarch64_borrow_operation" ""))
|
||||
(sign_extend:<DWI>
|
||||
(minus:GPI (match_dup 1)
|
||||
(match_operand:GPI 3 "aarch64_borrow_operation" "")))))
|
||||
(set (match_operand:GPI 0 "register_operand" "=r")
|
||||
(minus:GPI
|
||||
(match_dup 1) (match_dup 3)))]
|
||||
""
|
||||
"sbcs\\t%<w>0, %<w>1, <w>zr"
|
||||
[(set_attr "type" "adc_reg")]
|
||||
)
|
||||
|
||||
(define_insn "*sub<mode>3_carryinV"
|
||||
[(set (reg:CC_V CC_REGNUM)
|
||||
(compare:CC_V
|
||||
(minus:<DWI>
|
||||
(sign_extend:<DWI>
|
||||
(match_operand:GPI 1 "register_operand" "r"))
|
||||
(plus:<DWI>
|
||||
(sign_extend:<DWI>
|
||||
(match_operand:GPI 2 "register_operand" "r"))
|
||||
(match_operand:<DWI> 3 "aarch64_borrow_operation" "")))
|
||||
(sign_extend:<DWI>
|
||||
(minus:GPI
|
||||
(match_dup 1)
|
||||
(plus:GPI (match_operand:GPI 4 "aarch64_borrow_operation" "")
|
||||
(match_dup 2))))))
|
||||
(set (match_operand:GPI 0 "register_operand" "=r")
|
||||
(minus:GPI
|
||||
(minus:GPI (match_dup 1) (match_dup 2))
|
||||
(match_dup 4)))]
|
||||
""
|
||||
"sbcs\\t%<w>0, %<w>1, %<w>2"
|
||||
[(set_attr "type" "adc_reg")]
|
||||
)
|
||||
|
||||
(define_insn "*sub_uxt<mode>_shift2"
|
||||
[(set (match_operand:GPI 0 "register_operand" "=rk")
|
||||
(minus:GPI (match_operand:GPI 4 "register_operand" "rk")
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2019-01-07 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
* gcc.target/aarch64/subs_compare_2.c: Make '#' immediate prefix
|
||||
optional in scan pattern.
|
||||
|
||||
2019-01-07 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
PR tree-optimization/88598
|
||||
|
|
|
@ -11,5 +11,5 @@ foo (int a, int b)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-times "subs\\tw\[0-9\]+, w\[0-9\]+, #4" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "subs\\tw\[0-9\]+, w\[0-9\]+, \[#\]?4" 1 } } */
|
||||
/* { dg-final { scan-assembler-not "cmp\\tw\[0-9\]+, w\[0-9\]+" } } */
|
||||
|
|
Loading…
Add table
Reference in a new issue