Lowering Select to Two Predicated Movs

Hi,

I was wondering what would be the best way to lower a select operation two predicated movs. I looked through the ARM, MIPS, and NVPTX backends and they all seem to lower a select to some sort of conditional move or native select operation.

Ex.
select t3, cond, t2, t1

Becomes
cond mov t3, t2
!cond mov t3, t1

-Dilan

ARM lowers a select to a predicated mov. MOVCCr is a pseudo-instruction which gets expanded after instruction selection.

-Eli

My bad for not looking further. I’m still somewhat confused though. MOVCCr gets expanded in the ARMExpandPseudoInsts pass, and it still seems only a case of one instruction replacing the other.

My worry of emitting two instructions, is that a dead code pass will eliminate the first instruction cause it thinks the second instruction is defining the same register.

-Dilan

The output of MOVCCr is tied to the "false" input using RegConstraint. The register allocator puts the "false" value into the destination register, then MOVCCr gets expanded to a predicated MOVr which moves the "true" value into the destination register.

-Eli

Ohh, that makes sense. And is the reason the first instruction doesn’t get deleted because the ExpandPseudoInstructions pass occurs after Register Allocation and machine dead code elimination?

-Dilan

That's how it works right now, yes, but it's a bug, not the intended design. (Post-RA scheduling runs after ExpandPseudoInstructions, so we need accurate dependencies; I'm surprised we haven't seen any miscompiles.)

The correct way to represent the dependency is with an implicit use. See UpdatePredRedefs in IfConversion.cpp for an example.

-Eli

Cool, that all made sense. Thanks for the help and the useful code examples. Cleared things up.

-Dilan