This is an archive of the discontinued LLVM Phabricator instance.

[MIPS] Add handing of forbidden slot when IR with inline asm
Needs ReviewPublic

Authored by yingopq on Aug 23 2023, 1:13 AM.

Details

Summary

Modify:
Add a global variable 'CurForbiddenSlotAttr' to save current instruction`s forbidden slot and whether set reorder.
This is the judgment condition for whether to add nop.
We would add a couple of '.set noreorder' and '.set reorder' to wrap the current instruction and the next instruction.
Then we can get previous instruction`s forbidden slot attribute and whether set reorder by 'CurForbiddenSlotAttr'.
If previous instruction has forbidden slot and .set reorder is active and current instruction is CTI. Then emit a NOP
after it.

Fix scenarios:
1.When inline asm ends with branch instruction:
1.1)then compiler
generate another CTI immediately, CTI lie in forbidden slot.
test: Use function foo1 in new file llvm/test/CodeGen/Mips/llvm-ir/forbidden-slot-ir.ll.
1.2)and next IR line was also inline asm, need insert nop between them.
test: Use function foo2 in new file llvm/test/CodeGen/Mips/llvm-ir/forbidden-slot-ir.ll.
2.When inline asm includes CTI following branch instruction, need
insert nop between them.
test: Use function foo3 in new file llvm/test/CodeGen/Mips/llvm-ir/forbidden-slot-ir.ll.
3.Also add test for scenario that have been realized in pass, when
CTI follow branch instruction.
test: Use function foo0 in new file llvm/test/CodeGen/Mips/llvm-ir/forbidden-slot-ir.ll.
4.When .set reorder is set in handwritten assembly file, nop need
insert between branch instruction and CTI.
test: in new file llvm/test/MC/Mips/forbidden-slot.s

Test result:
$ sudo ./build/bin/llvm-lit -v llvm/test/CodeGen/Mips/llvm-ir/forbidden-slot-ir.ll llvm/test/MC/Mips/forbidden-slot.s llvm/test/MC/Mips/mips32r6/relocations.s llvm/test/MC/Mips/mips64r6/relocations.s llvm/test/MC/Mips/relocation.s
[sudo] password for huangyin:

  • Testing: 5 tests, 5 workers --

PASS: LLVM :: MC/Mips/mips32r6/relocations.s (1 of 5)
PASS: LLVM :: MC/Mips/mips64r6/relocations.s (2 of 5)
PASS: LLVM :: MC/Mips/forbidden-slot.s (3 of 5)
PASS: LLVM :: CodeGen/Mips/llvm-ir/forbidden-slot-ir.ll (4 of 5)
PASS: LLVM :: MC/Mips/relocation.s (5 of 5)
Testing Time: 0.25s
Total Discovered Tests: 5

Passed: 5 (100.00%)

Fix https://github.com/llvm/llvm-project/issues/61045

Diff Detail

Event Timeline

yingopq created this revision.Aug 23 2023, 1:13 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 23 2023, 1:13 AM
yingopq requested review of this revision.Aug 23 2023, 1:13 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 23 2023, 1:13 AM

I am quite concerned with extra parameters in AsmPrinter::emitInlineAsm, parseStatement, and similar member functions. Do we have a way not adding them?

@FlyGoat

llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h
95 ↗(On Diff #552617)

Don't repeat the variable/function name in new code.

96 ↗(On Diff #552617)

Do we have to have this variable?

llvm/test/MC/Mips/forbidden-slot.s
2

we cannot use clang in llvm tests due to layering reasons https://maskray.me/blog/2021-08-08-toolchain-testing#the-test-checks-at-the-wrong-layer. also, llvm-project may be built with just llvm, not clang, and this would fail.

5

Align instructions for better look

# MIPSELR6:      beqzc	$9, 0x8 <bbb>
# MIPSELR6-NEXT: nop <aaa>
# MIPSELR6:      b	0x8 <bbb>
jrtc27 requested changes to this revision.Aug 23 2023, 11:33 PM

With the exception of 5, these all sound like garbage inline asm input? If you have a dangling delay slot at the end of the inline assembly, that's your problem, not the compiler's. And don't we default to reorder, anyway, so the only way to write that is to first .set noreorder?

This revision now requires changes to proceed.Aug 23 2023, 11:33 PM

With the exception of 5, these all sound like garbage inline asm input? If you have a dangling delay slot at the end of the inline assembly, that's your problem, not the compiler's. And don't we default to reorder, anyway, so the only way to write that is to first .set noreorder?

Well forbidden slot works differs from delay slot. It is introduced in MIPS Release 6.
It does not change execution flow. It simply disallows some CTI instructions (namely branch etc) to be placed after a branch.
Requiring user to fill nop after all inline assembly that ends with those branch instructions sounds appealing.

With the exception of 5, these all sound like garbage inline asm input? If you have a dangling delay slot at the end of the inline assembly, that's your problem, not the compiler's. And don't we default to reorder, anyway, so the only way to write that is to first .set noreorder?

To make this problem more clear, this patch is about forbidden slot, not delay slot.
In MIPSr6, you cannot put a CTI (branch/jump instruction) just after another CTI, even they are compact(no delay slot),
so a nop is needed to insert.

I am quite concerned with extra parameters in AsmPrinter::emitInlineAsm, parseStatement, and similar member functions. Do we have a way not adding them?

@FlyGoat

I can't think of another way to achieve similiar functionality.

Another possible method is to let MC process forbidden-slot even with noreorder set.

FlyGoat added a comment.EditedAug 24 2023, 12:07 AM

FYI Github issue I raised for this problem: https://github.com/llvm/llvm-project/issues/61045

Please update into commit message next time.

If the patch is related to https://github.com/llvm/llvm-project/issues/61045 , the convention is to add

"Fix https://github.com/llvm/llvm-project/issues/61045" or "Close https://github.com/llvm/llvm-project/issues/61045" to the local commit message and update the summary (arc diff --head=HEAD 'HEAD^' --verbatim amends the summary with the local commit message when uploading a new diff). Personally I prefer "Close" for features.

yingopq edited the summary of this revision. (Show Details)Nov 9 2023, 10:36 PM
yingopq updated this revision to Diff 558070.Nov 9 2023, 10:58 PM

Add a global variable 'CurForbiddenSlotAttr' to save current instruction`s forbidden slot and whether set reorder.
This is the judgment condition for whether to add nop.
We would add a couple of '.set noreorder' and '.set reorder' to wrap the current instruction and the next instruction.
Then we can get previous instruction`s forbidden slot attribute and whether set reorder by 'CurForbiddenSlotAttr'.
If previous instruction has forbidden slot and .set reorder is active and current instruction is CTI. Then emit a NOP
after it.

yingopq updated this revision to Diff 558091.Nov 14 2023, 1:03 AM
yingopq added a reviewer: craig.topper.

Fix fail test "lld/test/ELF/mips-pc-relocs.s"

yingopq added a comment.EditedNov 14 2023, 1:12 AM
This comment has been deleted.
llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h
95 ↗(On Diff #552617)

Don't repeat the variable/function name in new code.

You mean we should use another name, not MIp?

96 ↗(On Diff #552617)

Do we have to have this variable?

In function MatchAndEmitInstruction, we use this structure Info.ParsedOperands to pass MI to target backend MIPS which need use MI to get next instruction of MBB.

llvm/test/MC/Mips/forbidden-slot.s
2

OK, thanks, I would use llvm-mc, like this llvm-mc -assemble -mcpu=mips64r6 -arch=mips64el -filetype=obj %s -o tmp.o.

$ ./build/bin/llvm-lit -v llvm/test/MC/Mips/forbidden-slot.s

  • Testing: 1 tests, 1 workers --

PASS: LLVM :: MC/Mips/forbidden-slot.s (1 of 1)

Testing Time: 0.07s

Passed: 1

@craig.topper Could you kindly help review this issue patch at your convenience, thanks!

yingopq updated this revision to Diff 558102.Nov 14 2023, 7:24 PM

Ping,
Thanks