On 1/23/2026 7:49 AM, Stefan Schulze Frielinghaus wrote:
On Thu, Jan 22, 2026 at 09:55:42AM -0700, Jeffrey Law wrote:
On 1/16/2026 7:29 AM, Stefan Schulze Frielinghaus wrote:
The likely-spilled classes machinery can't be used as-is since the decision
for your case is dependent upon context (ie, the insn itself and its
constraints). So perhaps what we want is your code to peek at the
constraints, but bolted onto the code that's checking for the likely-spilled
classes?
My knowledge about cse is very thin and so far I don't see how to
implement this in hash_rtx() or tight this with likely-spilled classes.
For example, having
1: r100=%1
2: r101=...
3: r102=exp_a(r100)
4: r103=exp_b(r101)
5: r104=exp_c(r100)
Assume that insn 3 has no hard register constraint, but insn 4 does
which is referring to hard register %1. Then I would still like to keep
track that r100 and %1 hold the same value, while analyzing insn 1,
which enables me to substitute r100 by %1 in insn 3. For insn 4,
however, I would like to invalidate this relation, since operand r101 is
potentially loaded into %1 and would clobber the register. Explicitly
clobbering/invalidating register %1 while analyzing insn 4 ensures that
r100 is not substituted by %1 in insn 5.
Thus, at first encounter I still want to hash a hard register and at
some later point once I encounter a hard register constraint referring to
the same hard register, I want to invalidate it. To be conservative
here, I do this irrespective whether an alternative is likely, unlikely,
or whatsoever. Basically I'm treating a hard register constraint as a
possible load.
In that regard hard register constraints may not be as restrictive as
single register classes, since for the latter even a substitution into
insn 3 wouldn't be done if I read the current implementation correctly.
The basic idea is that by setting "record" to false, the value won't be kept
in the hash table and it won't be subject to CSE going forward. For your
scenario I think we still have a problem; but I don't see a great solution.
Essentially at 1, you don't know if %1 is safe to have its lifetime
extended. That's the key difference -- more context is needed for the
single register constraint issues.
Yes, there is basically one contract which has to be fulfilled at the
moment: A hard register N must not be live at an insn which constraints
an operand to hard register N via a hard register constraint or a
constraint referring to a single register class. That would be a bug
coming either from an optimization or if the target emits a sequence of
instructions where we have assignments to hard registers and usages of
hard register constraints referring to the same hard register.
Assume that in the following r100 is constraint to hard register %1 in
insn 1 and 3. Furthermore, assume that hard register %1 becomes dead
between insn 2 and 3.
1: r101=exp_a(r100)
...
2: %r1=...
...
3: r102=exp_b(r100)
Then r100 would be assigned %r1 for insn 1 and spilled prior insn 2 and
reloaded just after insn 2 as soon as %1 becomes dead. Thus, between
insn 2 and 3 the lifetime of %1 may be extended assuming that no other
insn has a single register constraint referring to %1. The important
part is that %1 becomes dead somewhere before insn 3, i.e., I have to
prevent CSE to extend the lifetime of register %1 across insn 3.
ISTM that you have to invalidate the relevant hash table entries at 4. Not
sure the best way to do that, most of CSE has fallen out of my brain through
the years.
Isn't this what is happening by this patch during
invalidate_from_sets_and_clobbers() where we have the context in form of
the insn? I'm basically removing all hash table entries which are
related to a register which is referred by any hard register constraint.
That should prevent CSE to propagate a hard register any further.
Yea, it just took me a little time to reach the conclusion that this has
to be handled as an invalidation problem, not as a "avoid putting
something into the hash table" problem. Now that I'm on board with
that key concept, it's obvious to me that your patch is a reasonable
solution.
OK for the trunk. Thanks for your patience.
Jeff
Cheers,
Stefan