Björn Pettersson A via llvm-dev
2019-Sep-27 13:07 UTC
[llvm-dev] What about multiple MachineMemOperands in one MI (BranchFolding/MachineInstr::mayAlias)?
Hi! Does anyone know how it should be interpreted when one MI has multiple MachineMemOperands? (I've tried to find information but could not find any clear definition.) For example BranchFolder may do things like this (also see https://godbolt.org/z/iphFH4): # *** IR Dump Before Control Flow Optimizer ***: bb.0.entry: ... JCC_1 %bb.2, 5, implicit killed $eflags JMP_1 %bb.1 bb.1.s1: CALL64pcrel32 @bar, ... , implicit-def $rax MOV16mr killed renamable $rax, 1, $noreg, 0, $noreg, renamable $bx :: (store 2 into %ir.r) JMP_1 %bb.3 bb.2.s2: CALL64pcrel32 @bar, ... , implicit-def $rax MOV16mr killed renamable $rax, 1, $noreg, 0, $noreg, renamable $bx :: (store 2 into %ir.r2) bb.3.cond.end: ... # *** IR Dump After Control Flow Optimizer ***: bb.0.entry: ... CALL64pcrel32 @bar, ... , implicit-def $rax MOV16mr killed renamable $rax, 1, $noreg, 0, $noreg, renamable $bx :: (store 2 into %ir.r2), (store 2 into %ir.r) ... So after branch folding we get a single store with two MachineMemOperands. Obviously we do not store into two locations (it is still a single two byte store). So is it (always) correct to interpret the list of MachineMemOperands as the instruction will store to one of the locations? Is perhaps allowed for a backend to have a store instruction that that actually stores to multiple locations at once, such as: MultiStoreInstr $ptr0, 1, $ptr1, 2, $ptr2, 18 :: (store 2 intro %my.ptr0.var), (store 2 intro %my.ptr1.var), (store 2 intro %my.ptr2.var) (maybe that is impossible for other reasons). Background to my questions: The problem with the rewrite done by BranchFolder is that it sometimes mess up alias analysis. In fact, MachineInstr::mayAlias bails out when it finds an MI with more (or less) than one MachineMemOperand. So if we have (trivially non aliasing) stores like this before branch folding STORE ... :: (store 2 into %struct) STORE ... :: (store 2 into %struct + 2) then we get this after branch folding STORE ... :: (store 2 into %struct), (store 2 into %struct.2) STORE ... :: (store 2 into %struct + 2), (store 2 into %struct.2 + 2) and then MachineInstr::mayAlias fail to detect the stores as not aliasing. Without knowing how to interpret the situation with multiple MachineMemOperands I guess it is hard to improve the analysis. Maybe BranchFolding could do something better here (is it a bug to add multiple operands like this?). Regards, Björn
Matt Arsenault via llvm-dev
2019-Sep-27 14:33 UTC
[llvm-dev] What about multiple MachineMemOperands in one MI (BranchFolding/MachineInstr::mayAlias)?
> On Sep 27, 2019, at 09:07, Björn Pettersson A via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > Obviously we do not store into two locations (it is still a single two byte store). > So is it (always) correct to interpret the list of MachineMemOperands as the instruction will store to one of the locations?I think it’s bug to have multiple memory operands if the instruction only accesses one location. The operands should have been merged in some way unless the instruction can truly access two distinct addresses -Matt -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190927/77533110/attachment.html>
Philip Reames via llvm-dev
2019-Sep-27 16:28 UTC
[llvm-dev] What about multiple MachineMemOperands in one MI (BranchFolding/MachineInstr::mayAlias)?
On 9/27/19 7:33 AM, Matt Arsenault via llvm-dev wrote:> > >> On Sep 27, 2019, at 09:07, Björn Pettersson A via llvm-dev >> <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote: >> >> Obviously we do not store into two locations (it is still a single >> two byte store). >> So is it (always) correct to interpret the list of MachineMemOperands >> as the instruction will store to one of the locations? > > I think it’s bug to have multiple memory operands if the instruction > only accesses one location. The operands should have been merged in > some way unless the instruction can truly access two distinct addressesI'm a bit less sure of this. It's on the surface reasonable, but there are some interesting questions. We definitely interpret a list of MMOs as indicating a set of locations which are possibly(?) accessed. The only piece I'm unsure about is that the existence of an MMO requires the access occurs. If we do, that raises some interesting consistency questions for cases such as: * Load/Store merging (a superset of the branch folding case) * Predicate loads and stores (since the access may not happen) * Load/stores in dead code (i.e. the typical UB contradiction cases) * Instructions w/multiple accesses to the same MMO combined w/constant memory to imm folding which only handles some cases I'm tempted to suggest we treat the list of MMOs as a potential superset of the implied access, not a direct one-to-one mapping. (None of this should imply branch folding shouldn't merge the MMOs. That would just become an optimization quality issue, not a correctness one.) Philip> > -Matt > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190927/b022bc6c/attachment.html>