diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md index 548c36979f1..f9e89e991d9 100644 --- a/gcc/config/arm/thumb1.md +++ b/gcc/config/arm/thumb1.md @@ -1810,6 +1810,34 @@ (set_attr "type" "multiple")] ) +;; Re-split an LEU/GEU sequence if combine tries to oversimplify a 3-plus +;; insn sequence. Beware of the early-clobber of operand0 +(define_split + [(set (match_operand:SI 0 "s_register_operand") + (leu:SI (match_operand:SI 1 "s_register_operand") + (match_operand:SI 2 "s_register_operand")))] + "TARGET_THUMB1 + && !reg_overlap_mentioned_p (operands[0], operands[1]) + && !reg_overlap_mentioned_p (operands[0], operands[2])" + [(set (match_dup 0) (const_int 0)) + (set (match_dup 0) (plus:SI (plus:SI (match_dup 0) (match_dup 0)) + (geu:SI (match_dup 2) (match_dup 1))))] + {} +) + +(define_split + [(set (match_operand:SI 0 "s_register_operand") + (geu:SI (match_operand:SI 1 "s_register_operand") + (match_operand:SI 2 "thumb1_cmp_operand")))] + "TARGET_THUMB1 + && !reg_overlap_mentioned_p (operands[0], operands[1]) + && !reg_overlap_mentioned_p (operands[0], operands[2])" + [(set (match_dup 0) (const_int 0)) + (set (match_dup 0) (plus:SI (plus:SI (match_dup 0) (match_dup 0)) + (geu:SI (match_dup 1) (match_dup 2))))] + {} +) + (define_insn "*thumb_jump" [(set (pc) diff --git a/gcc/testsuite/gcc.target/arm/unsigned-extend-1.c b/gcc/testsuite/gcc.target/arm/unsigned-extend-1.c index 3b4ab048fb0..fa3d34400bf 100644 --- a/gcc/testsuite/gcc.target/arm/unsigned-extend-1.c +++ b/gcc/testsuite/gcc.target/arm/unsigned-extend-1.c @@ -5,5 +5,5 @@ unsigned char foo (unsigned char c) { return (c >= '0') && (c <= '9'); } - -/* { dg-final { scan-assembler-not "uxtb" } } */ +/* We shouldn't need any zero-extension idioms here. */ +/* { dg-final { scan-assembler-not "\t(uxtb|and|lsr|lsl)" { xfail arm_thumb1 } } } */