On 2/15/2026 11:27 AM, Jeffrey Law wrote:
On 2/14/2026 1:28 PM, Andrew Pinski wrote:
On Sat, Feb 14, 2026 at 3:48 AM Daniel Barboza
<[email protected]> wrote:
Add a new helper that handles mispredicts in the following bit ops
scenarios:
- checking if a bitmask is not set, and in this case set it: always set
the bitmask;
- checking if a bitmask is set, and in this case clear it: always clear
the bitmask.
Bootstrapped and tested with x86_64-pc-linux-gnu.
This is NOT a full review, just something which caught my eye.
And just a note, the goal here is to clean up that mispredict in
bitmap_{set,clear}_bit which shows up in spec2017's 502.gcc. Andi
fixed it up by changing the sources of those routines for our tree, but
obviously that doesn't help spec2017 :-)
This was either the #1 or #2 source of mispredicts in at least one input
of 502.gcc, hence the focus on trying to cleanly if-convert it and
eliminate the branch.
The phiopt implementation this patch is using is based on the bitmap_set_bit pattern, but
unfortunately it's not enough to solve it. There are at least 2 reasons:
- that pattern has a triple node PHI in the end. phiopt isn't able to handle
that
properly. Andrew is looking into it in his work @ 123113 so at least this
limitation will
be soon gone;
- even if we reduce to the simpler case with just 2 PHI nodes, phiopt thinks
that the
PHI has 2 equal args and will skip the phi. This happens in
single_non_singleton_phi_for_edges(), then operand_equal_for_phi_arg_p():
static gphi *
single_non_singleton_phi_for_edges (gimple_seq seq, edge e0, edge e1)
{
gimple_stmt_iterator i;
gphi *phi = NULL;
for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
{
gphi *p = as_a <gphi *> (gsi_stmt (i));
/* If the PHI arguments are equal then we can skip this PHI. */
if (operand_equal_for_phi_arg_p (gimple_phi_arg_def (p, e0->dest_idx),
gimple_phi_arg_def (p, e1->dest_idx)))
continue;
So if we have a PHI like this:
--------
# RANGE [irange] long unsigned int [1, +INF]
_5 = _2 | bit_val_9;
# .MEM_14 = VDEF <.MEM_10(D)>
ptr_11(D)->bitsD.2963[word_num_12(D)] = _5;
;; succ: 4 (FALLTHRU,EXECUTABLE)
;; basic block 4, loop depth 0, maybe hot
;; prev block 3, next block 1, flags: (NEW, VISITED)
;; pred: 2 (FALSE_VALUE,EXECUTABLE)
;; 3 (FALLTHRU,EXECUTABLE)
# .MEM_6 = PHI <.MEM_10(D)(2), .MEM_14(3)>
-------------
operand_equal_for_phi_arg_p seems to be returning 'true' for these operands. My guess is
that the code thinks that they're the same because they point to the same memory address.
Not sure if we can add an exception in this function for this pattern ...
Alas, Andrew told me offline a while ago that this pattern can be handled elsewhere
(cselim), so we still have some ways forward. I'll get to that after sending these
phiopt/match.pd related work to the ML (bugs 56110 and 123967).
Thanks,
Daniel
Jeff