Skip to content

Commit a035cf1

Browse files
committed
arc: emit clobber of CC for -mcpu=em x >> 31
Address the issue explained here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120375 Devices without a barrel shifter end up using a sequence of instructions. These can use the condition codes and/or loop count register, so those need to be marked as 'clobbered'. These clobbers were previously added only after split1, which is too late. This patch adds these clobbers from the beginning, in the define_expand. Previously, define_insn_and_split *<insn>si3_nobs would match any shift or rotate instruction and would generate the necessary patterns to emulate a barrel shifter, but it did not have any output assembly for itself. In many cases this would create a loop with parallel clobbers. This pattern is then matched by the <insn>si3_loop pattern. Now, these are combined in define_insn_and_split <insn>si3_loop that is explicitly emitted in the define_expand and already contains the clobbers. This can then be split into another pattern or remain the loop pattern. Regtested for arc. Signed-off-by: Loeka Rogge <[email protected]>
1 parent ef2d980 commit a035cf1

File tree

2 files changed

+54
-25
lines changed

2 files changed

+54
-25
lines changed

gcc/config/arc/arc.md

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3554,7 +3554,14 @@ archs4x, archs4xd"
35543554
[(set (match_operand:SI 0 "dest_reg_operand" "")
35553555
(ANY_SHIFT_ROTATE:SI (match_operand:SI 1 "register_operand" "")
35563556
(match_operand:SI 2 "nonmemory_operand" "")))]
3557-
"")
3557+
""
3558+
{
3559+
if (!TARGET_BARREL_SHIFTER && operands[2] != const1_rtx)
3560+
{
3561+
emit_insn (gen_<insn>si3_loop (operands[0], operands[1], operands[2]));
3562+
DONE;
3563+
}
3564+
})
35583565

35593566
; asl, asr, lsr patterns:
35603567
; There is no point in including an 'I' alternative since only the lowest 5
@@ -3653,35 +3660,23 @@ archs4x, archs4xd"
36533660
[(set_attr "type" "shift")
36543661
(set_attr "length" "8")])
36553662

3656-
(define_insn_and_split "*<insn>si3_nobs"
3657-
[(set (match_operand:SI 0 "dest_reg_operand")
3658-
(ANY_SHIFT_ROTATE:SI (match_operand:SI 1 "register_operand")
3659-
(match_operand:SI 2 "nonmemory_operand")))]
3663+
(define_insn_and_split "<insn>si3_loop"
3664+
[(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
3665+
(ANY_SHIFT_ROTATE:SI (match_operand:SI 1 "register_operand" "0,0")
3666+
(match_operand:SI 2 "nonmemory_operand" "rn,Cal")))
3667+
(clobber (reg:SI LP_COUNT))
3668+
(clobber (reg:CC CC_REG))]
36603669
"!TARGET_BARREL_SHIFTER
3661-
&& operands[2] != const1_rtx
3662-
&& arc_pre_reload_split ()"
3663-
"#"
3664-
"&& 1"
3670+
&& operands[2] != const1_rtx"
3671+
"* return output_shift_loop (<CODE>, operands);"
3672+
"&& arc_pre_reload_split ()"
36653673
[(const_int 0)]
36663674
{
36673675
arc_split_<insn> (operands);
36683676
DONE;
3669-
})
3670-
3671-
;; <ANY_SHIFT_ROTATE>si3_loop appears after <ANY_SHIFT_ROTATE>si3_nobs
3672-
(define_insn "<insn>si3_loop"
3673-
[(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
3674-
(ANY_SHIFT_ROTATE:SI
3675-
(match_operand:SI 1 "register_operand" "0,0")
3676-
(match_operand:SI 2 "nonmemory_operand" "rn,Cal")))
3677-
(clobber (reg:SI LP_COUNT))
3678-
(clobber (reg:CC CC_REG))
3679-
]
3680-
"!TARGET_BARREL_SHIFTER
3681-
&& operands[2] != const1_rtx"
3682-
"* return output_shift_loop (<CODE>, operands);"
3683-
[(set_attr "type" "shift")
3684-
(set_attr "length" "16,20")])
3677+
}
3678+
[(set_attr "type" "shift")
3679+
(set_attr "length" "16,20")])
36853680

36863681
;; DImode shifts
36873682

@@ -6413,6 +6408,21 @@ archs4x, archs4xd"
64136408
(set_attr "length" "4")
64146409
(set_attr "predicable" "no")])
64156410

6411+
;; Match <insn>si3_loop pattern if operand 2 has become const_int 1 in the meantime
6412+
(define_insn_and_split "<insn>si3_cnt1_clobber"
6413+
[(set (match_operand:SI 0 "dest_reg_operand")
6414+
(ANY_SHIFT_ROTATE:SI (match_operand:SI 1 "register_operand")
6415+
(const_int 1)))
6416+
(clobber (reg:SI LP_COUNT))
6417+
(clobber (reg:CC CC_REG))]
6418+
"!TARGET_BARREL_SHIFTER"
6419+
"#"
6420+
"&& arc_pre_reload_split ()"
6421+
[(set (match_dup 0) (ANY_SHIFT_ROTATE:SI (match_dup 1) (const_int 1)))]
6422+
""
6423+
[(set_attr "type" "shift")
6424+
(set_attr "length" "4")])
6425+
64166426
(define_peephole2
64176427
[(set (match_operand:SI 0 "register_operand" "")
64186428
(zero_extract:SI (match_dup 0)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/* { dg-do compile } */
2+
/* { dg-options "-O2" } */
3+
/* { dg-skip-if "" { { barrelshifter } } } */
4+
int fromfloat(float fx);
5+
6+
float foo(float fx)
7+
{
8+
int x = fromfloat(fx);
9+
int sign = (x >> 31) & 1;
10+
unsigned int mag = x & 0x7fffffff;
11+
12+
if (mag > 0x7f800000)
13+
return fx;
14+
if (mag == 0x7f800000)
15+
return (sign == 0);
16+
return fx * (27 + sign);
17+
}
18+
19+
/* { dg-final { scan-assembler-not "add.f\\s\+\[0-9\]\+,r\[0-9\]\+,r\[0-9\]\+\\n\\s\+beq.d" } } */

0 commit comments

Comments
 (0)