This is an archive of the discontinued LLVM Phabricator instance.

[GlobalISel] Don't add duplicate successors to MBBs when translating indirectbr
ClosedPublic

Authored by paquette on May 7 2020, 4:44 PM.

Details

Summary

This fixes a verifier failure on a bot:

http://green.lab.llvm.org/green/job/test-suite-verify-machineinstrs-aarch64-O0-g/

*** Bad machine code: MBB has duplicate entries in its successor list. ***
- function:    foo
- basic block: %bb.5 indirectgoto (0x7fe3d687ca08)

One of the GCC torture suite tests (pr70460.c) has an indirectbr instruction which has duplicate blocks in its destination list.

According to the langref this is allowed:

Blocks are allowed to occur multiple times in the destination list, though this isn’t particularly useful.

(https://www.llvm.org/docs/LangRef.html#indirectbr-instruction)

We don't allow this in MIR. So, when we translate such an instruction, the verifier screams.

This patch makes translateIndirectBr check if a successor has already been added to a block. If the successor is present, it is skipped rather than added twice.

Diff Detail

Event Timeline

paquette created this revision.May 7 2020, 4:44 PM
Herald added a project: Restricted Project. · View Herald TranscriptMay 7 2020, 4:44 PM
arsenm added inline comments.May 8 2020, 8:25 AM
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
843–848

I believe isSuccessor is a linear scan. This should use a pointer set like SelectionDAGBuilder

paquette updated this revision to Diff 262892.May 8 2020, 10:03 AM
paquette marked an inline comment as done.

Use SmallSet like SelectionDAGBuilder does.

arsenm accepted this revision.May 8 2020, 11:15 AM
arsenm added inline comments.
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
841

SmallPtrSet, not sure what the differences iss

This revision is now accepted and ready to land.May 8 2020, 11:15 AM
paquette marked an inline comment as done.May 8 2020, 12:02 PM
paquette added inline comments.
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
841

According to the programmer's manual it sounds like it should basically be the same?

"(and a SmallSet of pointers is transparently implemented with a SmallPtrSet)"

and in SmallSet.h:

/// If this set is of pointer values, transparently switch over to using
/// SmallPtrSet for performance.

I don't mind switching it to SmallPtrSet for clarity though.

This revision was automatically updated to reflect the committed changes.