This is an archive of the discontinued LLVM Phabricator instance.

[RegAlloc] Fix assertion failure caused by inline assembly
ClosedPublic

Authored by Qi-Hu on Jul 12 2023, 7:58 AM.

Details

Summary

When inline assembly requests more registers than available, the MachineInstr::emitError function in the RegAllocFast pass emits an error but doesn't stop the pass. Then the compiler crashes at an assertion error. This commit, mimicking the RegAllocGreedy pass, assigns a random physical register, and therefore avoids the crash. This error has been found for both rust and clang, while it doesn't occur in gcc.

Diff Detail

Event Timeline

Qi-Hu created this revision.Jul 12 2023, 7:58 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 12 2023, 7:58 AM
Qi-Hu requested review of this revision.Jul 12 2023, 7:58 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 12 2023, 7:58 AM
Qi-Hu retitled this revision from Fix assertion failure caused by inline assembly to [CodeGen] Fix assertion failure caused by inline assembly.Jul 12 2023, 8:06 AM
Qi-Hu updated this revision to Diff 539738.Jul 12 2023, 2:35 PM
bryanpkc added inline comments.Jul 12 2023, 2:53 PM
llvm/lib/CodeGen/RegAllocFast.cpp
838

MachineInstr::emitError falls back to calling report_fatal_error if it cannot find a MCContext. Making an additional call to report_fatal_error here doesn't feel right. Why isn't MI.emitError able to stop the compiler before it crashes?

bryanpkc added inline comments.Jul 12 2023, 3:03 PM
llvm/lib/CodeGen/RegAllocFast.cpp
838

MachineInstr::emitError falls back to calling report_fatal_error if it cannot find a MCContext.

I meant LLVMContext, not MCContext.

Qi-Hu updated this revision to Diff 540077.Jul 13 2023, 9:31 AM
Qi-Hu edited the summary of this revision. (Show Details)
Qi-Hu added inline comments.Jul 13 2023, 9:45 AM
llvm/lib/CodeGen/RegAllocFast.cpp
838

emitError is designed to return and does not stop the pass. In fact, given the same test case, RegAllocGreedy also reports the error but ends up generating bogus assembly, without crashing. I have updated the patch to mimic that behaviour, by copying some existing logic from useVirtReg.

bryanpkc added inline comments.Jul 13 2023, 11:02 AM
llvm/lib/CodeGen/RegAllocFast.cpp
838

OK thanks.

937–944

This line should be concatenated to the previous line, to match LLVM coding style.

952–953

I guess this assert is no longer necessary?

bryanpkc added inline comments.Jul 13 2023, 2:05 PM
llvm/lib/CodeGen/RegAllocFast.cpp
941

Why doesn't this return the result of setPhysReg?

You should also add a comment to explain that since there was an error finding a suitable register for LRI, we just pick a register at random and bail out of the function immediately.

Qi-Hu updated this revision to Diff 540191.Jul 13 2023, 3:02 PM

LGTM, but I would wait for others to confirm whether this is an acceptable fix.

bryanpkc added inline comments.Jul 13 2023, 4:17 PM
llvm/test/CodeGen/X86/inline-asm-assertion.ll
3

Suggestions:

  1. Add a CHECK line to match the output assembly, e.g. ; CHECK: .size main, .Lfunc_end0-main, to ensure that that the backend does not crash after register allocation.
  2. Add a RUN line with llc -O2 to ensure that RegAllocGreedy behaves the same way.
arsenm added inline comments.Jul 14 2023, 8:41 AM
llvm/test/CodeGen/X86/inline-asm-assertion.ll
3

Could also add -verify-machineinstrs, it may fail already with expensive checks. I was working on fixing verifier errors after regalloc failure but haven't finished it

60

Can probably drop most of these attributes

Qi-Hu updated this revision to Diff 542115.Jul 19 2023, 11:00 AM
Qi-Hu retitled this revision from [CodeGen] Fix assertion failure caused by inline assembly to [RegAlloc] Fix assertion failure caused by inline assembly.
Qi-Hu added inline comments.Jul 19 2023, 11:11 AM
llvm/test/CodeGen/X86/inline-asm-assertion.ll
3

That's a good point. However, adding MachineVerifier reports a fatal error for llc -O2: "Bad machine code: Using an undefined physical register".

arsenm added inline comments.Jul 19 2023, 11:56 AM
llvm/test/CodeGen/X86/inline-asm-assertion.ll
3

Which is another bug which needs to be fixed

arsenm added inline comments.Jul 19 2023, 12:04 PM
llvm/test/CodeGen/X86/inline-asm-assertion.ll
2

Don't need the REQUIRES, it's implied by the x86 directory

arsenm added inline comments.Jul 19 2023, 1:36 PM
llvm/test/CodeGen/X86/inline-asm-assertion.ll
3

If it's failing the verifier after this, you should check the verification message. You'll need to handle that to not break EXPENSIVE_CHECKS testing. You can fix the additional verifier error separately though

Qi-Hu updated this revision to Diff 543054.Jul 21 2023, 1:57 PM
Qi-Hu added inline comments.Jul 21 2023, 2:00 PM
llvm/test/CodeGen/X86/inline-asm-assertion.ll
3

I don't know how to fix the verifier error at this point, but I agree that it should be handled as a separate issue.

Qi-Hu marked 3 inline comments as done and 3 inline comments as done.Jul 24 2023, 1:55 PM
Qi-Hu marked 9 inline comments as done.
arsenm added inline comments.Jul 24 2023, 2:17 PM
llvm/lib/CodeGen/RegAllocFast.cpp
941

Should also guard against AllocationOrder being empty which can happen if all the registers become reserved, I guess you just have to use noreg at that point

arsenm accepted this revision.Jul 24 2023, 2:17 PM
This revision is now accepted and ready to land.Jul 24 2023, 2:17 PM
bryanpkc added inline comments.Jul 25 2023, 2:00 PM
llvm/lib/CodeGen/RegAllocFast.cpp
941

@arsenm This pass uses emitError to indicate that the IR is no longer valid, but is still required to continue and complete register allocation. If we enter this code path, we don't expect to generate correct code anyway, so I think it should be okay to skip the check, both here and in useVirtReg.

arsenm added inline comments.Jul 25 2023, 2:05 PM
llvm/lib/CodeGen/RegAllocFast.cpp
941

If AllocationOrder is empty the compiler will just immediately crash which is not helpful

bryanpkc added inline comments.Jul 25 2023, 2:06 PM
llvm/lib/CodeGen/RegAllocFast.cpp
941

I see, I had misread your comment. Thanks.

Qi-Hu updated this revision to Diff 544105.Jul 25 2023, 2:38 PM
Qi-Hu marked 4 inline comments as done.
Qi-Hu updated this revision to Diff 544110.Jul 25 2023, 3:01 PM
arsenm accepted this revision.Jul 25 2023, 3:10 PM