From dad3c18fbb481ab31f1586b8f980940fa55951b8 Mon Sep 17 00:00:00 2001 From: Georg-Johann Lay Date: Sun, 21 May 2023 18:54:21 +0200 Subject: [PATCH] target/90622: __builtin_avr_insert bits: Use BLD/BST for one bit in place. If just one bit is inserted in the same position like with: __builtin_avr_insert_bits (0xFFFFF2FF, src, dst); a BLD/BST sequence is better than XOR/AND/XOR. Thus, don't fold that case to the latter sequence. gcc/ PR target/90622 * config/avr/avr.cc (avr_fold_builtin) [AVR_BUILTIN_INSERT_BITS]: Don't fold to XOR / AND / XOR if just one bit is copied to the same position. --- gcc/config/avr/avr.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc index d5af40f7091..9fa50ca230d 100644 --- a/gcc/config/avr/avr.cc +++ b/gcc/config/avr/avr.cc @@ -14425,10 +14425,13 @@ avr_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *arg, if (changed) return build_call_expr (fndecl, 3, tmap, tbits, tval); - /* If bits don't change their position we can use vanilla logic - to merge the two arguments. */ + /* If bits don't change their position, we can use vanilla logic + to merge the two arguments... */ - if (avr_map_metric (map, MAP_NONFIXED_0_7) == 0) + if (avr_map_metric (map, MAP_NONFIXED_0_7) == 0 + // ...except when we are copying just one bit. In that + // case, BLD/BST is better than XOR/AND/XOR, see PR90622. + && avr_map_metric (map, MAP_FIXED_0_7) != 1) { int mask_f = avr_map_metric (map, MAP_MASK_PREIMAGE_F); tree tres, tmask = build_int_cst (val_type, mask_f ^ 0xff);