abrown opened PR #3682 from isle-select
to main
:
This change ports CLIF's
select
instruction to ISLE for x64.
abrown requested fitzgen for a review on PR #3682.
abrown requested cfallin for a review on PR #3682.
abrown updated PR #3682 from isle-select
to main
.
abrown updated PR #3682 from isle-select
to main
.
abrown submitted PR review.
abrown created PR review comment:
@cfallin, I believe this test is incorrect--both previously and with the current lowering. By first moving
%xmm0
to%xmm1
withmovaps
, the flag-checking jumps really have no effect (they just move almost the same data again). Thoughts?
abrown submitted PR review.
abrown created PR review comment:
Zooming out: not only was the
FloatCC::Equal
lowering incorrect for FP, but there are no tests (that I can see) that exercise the other variants.
abrown edited PR review comment.
cfallin created PR review comment:
This overwrites
dst
from above, I think -- it seems we want the first cmove to write a tmp, andalternative
in the second to be that tmp? So then we have the equivalent ofcmove(cc1, a, cmove(cc2, b, alternative))
.
cfallin submitted PR review.
fitzgen submitted PR review.
fitzgen submitted PR review.
fitzgen created PR review comment:
Could this have a comment describing what it is?
fitzgen created PR review comment:
The
is_reg
prefix makes me think that these will extract fromReg
s but they actually will extract fromType
s. Can we rename these tois_{xmm,gpr}_type
instead perhaps?
fitzgen created PR review comment:
So this is
dst = if cc1 || cc2 { consequent } else { alternative }
right?
Could we maybe add that pseudocode to the comments for these variants? I think that will be very helpful for future readers.
fitzgen created PR review comment:
Sounds like we need some runtests for these
select
s, rather than just compile tests.
fitzgen created PR review comment:
;;;; Rules for `select` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; CLIF `select` instructions receive a testable argument (i.e. boolean or
fitzgen created PR review comment:
Alternatively, we could have them operate on
Reg
s and keep the current names. Then we would just have to adjust the call sites appropriately, which I think would be possible for all call sites since they also haveReg
s available.
abrown updated PR #3682 from isle-select
to main
.
abrown updated PR #3682 from isle-select
to main
.
abrown updated PR #3682 from isle-select
to main
.
abrown updated PR #3682 from isle-select
to main
.
abrown has marked PR #3682 as ready for review.
abrown updated PR #3682 from isle-select
to main
.
fitzgen submitted PR review.
fitzgen submitted PR review.
fitzgen created PR review comment:
I think these hard-coded sizes are fine, since we know an
i128
is represented with twoi64
GPRs.
fitzgen created PR review comment:
Doing the
emit
here is actually unsafe because nothing is guaranteeing that
- we just emitted the flags producer before this
- nothing else is emitted after the flags producer and before this flags consumer that clobbers the flags
What we want to do is return two
ConsumesFlags
here that we can then pass intowith_flags_2
along with aFlagsProducer
.ISLE doesn't have tuple/fixed-size-arrays support, so we will have to define an extern type for this.
But! The other rule for
cmove_from_values
for when it is a single-register value emits only oneConsumesFlags
, so I think we actually want an extern type that is either one or twoConsumesFlags
. I think we can just use aSmallVec<[ConsumesFlags; 2]>
.
fitzgen created PR review comment:
I think that
cmove_from_values
should take theseValueRegs
instead ofValue
s. This lets us reuse it in places where we've already put the values into registers.(decl cmove_from_values (Type CC ValueRegs ValueRegs) ConsumesFlags) (rule (cmove_from_vlaue $I128 cc consequent alternative) ...) ```` ~~~
fitzgen created PR review comment:
These rules look great, thanks!
fitzgen created PR review comment:
Note that we will want a
with_flags_*
variant that takes theSmallVec<[ConsumesFlags; 2]>
as well, and it will probably have to be implemented in external Rust code so it can loop over eachConsumesFlags
in the small vec.
fitzgen created PR review comment:
We need to have an extractor that ensure that this is a single-register type, as discussed before:
(rule (cmove_from_values (is_single_register_type ty) cc consequent alternative)
fitzgen created PR review comment:
Nitpick: we should clarify how we are combining the multiple flags here:
;; Helper for creating `cmove` instructions with the logical OR of multiple ;; flags. Note that these instructions will always result in more than one ;; emitted x86 instruction.
abrown submitted PR review.
abrown created PR review comment:
The downside to that is that it bloats the rules in
lower.isle
; can we do this refactoring in a future PR or issue, e.g., the next time cmove is used?
abrown updated PR #3682 from isle-select
to main
.
abrown submitted PR review.
abrown created PR review comment:
This sounds like a lot of new infrastructure to build and this PR may already have enough of that. The current lowering rules perform the same unsafe emission as this PR. Can't this be done afterwards?
abrown updated PR #3682 from isle-select
to main
.
abrown submitted PR review.
abrown created PR review comment:
Ok, I added an extractor that just checks that the type is not
I128
in fb334e1--can you take a look at that?
abrown updated PR #3682 from isle-select
to main
.
fitzgen submitted PR review.
fitzgen created PR review comment:
Sure, that works for me.
fitzgen submitted PR review.
fitzgen created PR review comment:
The current lowering rules for
select
are written in Rust, so it isn't really comparable. It would be one thing if thisemit
was near theemit
for the flags-producer instruction and theemit
for the other flags-consuming instruction, but it isn't. It isn't even clear to me, reading this code, that the instructions will always be emitted in the correct order!It seems to me that the order of evaluation will be something like
- construct
FlagsProducer
(do not emit it)- call this constructor
- emit first cmove
- construct FlagsConsumer with the second cmove
- call a
with_flags
variant with the constructedFlagsProducer
andFlagsConsumer
- emit the producer
- emit the consumer
If that is actually how things end up evaluating, then we would get
cmove; test/cmp; cmove
instead oftest/cmp; cmove; cmove
.It looks like we aren't testing
select
withi128
s yet (since you have only ported floating pointselect
s so far). But this is exactly the kind bug I want to avoid with a dedicatedwith_flags_*
variant that takesSmallVec<[ConsumesFlags; 2]>
, as described above.I really think we should fix this issue before landing this PR, or change this PR to not define and use
cmove_from_values
and instead use plaincmove
(which will work for all the single-register values forselect
that are are currently supported in ISLE).
cfallin updated PR #3682 from isle-select
to main
.
abrown submitted PR review.
abrown created PR review comment:
Ok, @cfallin and I (but mostly @cfallin), worked on this a bit. The unpolished results are in 667935f--@fitzgen, thoughts?
fitzgen submitted PR review.
fitzgen created PR review comment:
The extensions to
with_flags
,ProducesFlags
, andConsumesFlags
look good!
fitzgen submitted PR review.
fitzgen created PR review comment:
Looks good!
abrown updated PR #3682 from isle-select
to main
.
abrown updated PR #3682 from isle-select
to main
.
abrown requested fitzgen for a review on PR #3682.
abrown requested cfallin for a review on PR #3682.
cfallin submitted PR review.
fitzgen submitted PR review.
abrown updated PR #3682 from isle-select
to main
.
abrown updated PR #3682 from isle-select
to main
.
abrown merged PR #3682.
Last updated: Dec 23 2024 at 12:05 UTC