When creating the load from constant pool, check if there was already a load to the same constant, and abort if found.
The additional use of the load will prevent the pattern from memory folding the broadcast.
Details
Diff Detail
Event Timeline
A drive-by comment - regardless of whether we should be forming a vbroadcast for this case (I'll let you and Zvi figure it out :-) ), shouldn't we also have a pattern in place for the case we do?
X86InstrAVX512.td has a lot of X86SubVBroadcast patterns that are commented with:
Provide fallback in case the load node that is used in the patterns above
is used by additional users, which prevents the pattern selection.
But I don't see such a pattern for the v4i64 -> v8i64 case.
lib/Target/X86/X86ISelLowering.cpp | ||
---|---|---|
6414–6415 | X86ISD::VBROADCAST requires a memory operand only if the target is not AVX2. | |
6435–6436 | Would it be possible to check in advance if the Ld node is already used? | |
6445–6449 | Same as above. Early exit if we know in advance that Ld has already uses. | |
6450–6455 | I think it is safe to remove the else part. I think you can write something like this: if (Brdcst && !Ld.hasOneUse()) | |
6453–6456 | Phabricator doesn't let me delete this comment... |
A new review with the solution - offered by @mkuper - is up for review:
https://reviews.llvm.org/D27661
X86ISD::VBROADCAST requires a memory operand only if the target is not AVX2.
On AVX2, we should still be able to select a register-register variant of VBROADCAST from a X86ISD::VBROADCAST.
Basically (at least on AVX2) I don't think that a X86ISD::VBROADCAST is problematic even if we have load with multiple uses.