This is an archive of the discontinued LLVM Phabricator instance.

RISCV: handle 64-bit PCREL data relocations
ClosedPublic

Authored by compnerd on Jun 10 2022, 4:00 PM.

Details

Summary
We would previously fail to handle 64-bit PC-relative relocations on
RISCV.  This was exposed by trying to build with
`-fprofile-instr-generate`.

The original changes restricted the relocation handling to the text
segment as the paired relocations are undesirable in at least the debug
and .eh_frame sections. We now make this explicit to handle the general
case for the data relocations as well.

It would be preferable to use R_RISCV_n_PCREL when available to avoid
an extra relocation.

Fixes: #55971

Fixes: #55971

Diff Detail

Event Timeline

compnerd created this revision.Jun 10 2022, 4:00 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 10 2022, 4:00 PM
compnerd requested review of this revision.Jun 10 2022, 4:00 PM
MaskRay added inline comments.Jun 10 2022, 4:03 PM
llvm/test/MC/RISCV/instr-profile.s
1 ↗(On Diff #436068)

The test name should not attach to the specific instr-profile.s. It can be a generic filename indicating 64-bit PC-relative support. Other instrumentations may use 64-bit PCrel too.

compnerd updated this revision to Diff 436072.Jun 10 2022, 4:03 PM

I give up; the extra context seems to not paste in properly - the reduced context shows the diff properly. I can re-upload the extra context variant but it will render improperly.

compnerd updated this revision to Diff 436073.Jun 10 2022, 4:05 PM

Change filename as per @MaskRay's suggestion.

craig.topper added inline comments.Jun 10 2022, 5:39 PM
llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
236

Should relaxation here be relocation?

compnerd added inline comments.Jun 10 2022, 6:07 PM
llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
236

In the case of a compact code model, we can relax the pair of relocations to a single relocation. You would still have a relocation, it just is a nominally smaller file, and fewer relocations for the linker to process.

craig.topper added inline comments.Jun 10 2022, 7:21 PM
llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
236

I was asking about “Avoid relaxation for symbolic differences…”. Is relaxation the right word there?

compnerd added inline comments.Jun 11 2022, 6:16 PM
llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
236

Right; I believe that is the term here - we are technically relaxing the sequence by replacing the two relocations with one.

I give up; the extra context seems to not paste in properly - the reduced context shows the diff properly. I can re-upload the extra context variant but it will render improperly.

What exactly was the problem? I applied and regenerated the patch and uploaded it to Phabricator and it seemed fine. I tried it both as a file upload and as a paste.

llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
236

I've never seen "relaxation" being used that way. While that seems a reasonable generalization of how the term is typically used in compiler land, I suspect most people are going to be confused by the comment.

I know that this issue arose in the context of -fprofile-instr-generate but can you please clean up the test to focus on the bug? Something like this:

	.section	sx,"aw",@progbits
	.globl	x
x:

	.section	sy,"aw",@progbits
	.globl	y
y:
	.8byte	x-y
llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
232–234

This point is a bit of a nit-pick but that optimization isn't limited to when we are generating code for the compact code model. Rather, to define the compact code mode it's necessary to define that new relocation. Once we have support for that relocation (in the object code generator and the linker) we should be able to use it, whatever code model we are targeting. (The same point applies to the patch summary).

236–242

Are we testing all of these conditions?

compnerd added inline comments.Jun 13 2022, 8:13 AM
llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
232–234

I agree, it isn't limited to the compact code-model; were the relocation available in general, that would be preferable. I can try to reword this to make that more explicit.

236–242

This isn't new - this is the existing code path. I would assume that they are are being tested.

compnerd updated this revision to Diff 436464.Jun 13 2022, 10:21 AM

Apply changes from feedback from @luismarques

compnerd marked 3 inline comments as done.Jun 13 2022, 10:22 AM
luismarques accepted this revision.Jun 13 2022, 11:46 AM

LGTM.

(don't forget to update the commit message)

llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
232

Nit: maybe clarify that it's been proposed as part of the draft specs for the compact and large code models but not yet adopted. Otherwise people might not know what it's meant by "when available".

llvm/test/MC/RISCV/riscv64-64b-pcrel.s
2

Nit: wrap line

This revision is now accepted and ready to land.Jun 13 2022, 11:46 AM
MaskRay requested changes to this revision.Jun 13 2022, 12:11 PM

This is not ready to be pushed as is. I need some time to prepare a message.

This revision now requires changes to proceed.Jun 13 2022, 12:11 PM
MaskRay added inline comments.Jun 13 2022, 12:27 PM
llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
235

isInSection() checks defined non-absolute symbols. I think all the conditions here are to make MCDwarf.cpp use constants/32_PCREL if applicable.

Can S.getKind().isMetadata() unnecessarily match non-MCDwarf created sections?

Note that we have other functions (e.g. isTemporary) which are usable but I haven't thought hard for the best condition here.

llvm/test/MC/RISCV/riscv64-64b-pcrel.s
10

ADD/SUB are for labels. The definition isn't clear in the psABI, but in spirit they should be https://sourceware.org/binutils/docs/as/Symbol-Names.html local labels. At the very least they need to be STB_LOCAL.

Supporting STB_GLOBAL is fine as GNU as supports such subtraction for STB_GLOBAL for various ports but they can use a comment.

compnerd added inline comments.Jun 13 2022, 3:17 PM
llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
235

I don't think that isTemporary works. isMetadata shouldn't include anything that is marked as progbits or is part of the text or data segments.

llvm/test/MC/RISCV/riscv64-64b-pcrel.s
10

Sorry, I don't necessarily understand the exact action to take here.

MaskRay added inline comments.Jun 13 2022, 4:24 PM
llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
235

If the condition is match MCDwarf.cpp produced sections, testing section prefix .debug will be more specific.

isMetadata() catches a lot of non-debug non-SHF_ALLOC sections.

llvm/test/MC/RISCV/riscv64-64b-pcrel.s
10

Remove .global to test only the supported usage.

compnerd added inline comments.Jun 13 2022, 4:48 PM
llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
235

I do agree that doing a prefix-match for .debug is likely to be more conservative in what sections are excluded, but I am trying to be more conservative about generating the pairwise relocation. Avoiding the pair-wise relocations in non-SHF_ALLOC doesn't seem like a bad thing to me.

MaskRay added inline comments.Jun 13 2022, 4:51 PM
llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
235

That's fine with me, but IsDebugOrEHFrameSection needs to be renamed to reflect the truth.

compnerd updated this revision to Diff 436887.Jun 14 2022, 12:21 PM
compnerd marked 2 inline comments as done.
compnerd edited the summary of this revision. (Show Details)

Address feedback from @MaskRay .

MaskRay accepted this revision.Jun 14 2022, 12:30 PM
MaskRay added inline comments.
llvm/test/MC/RISCV/riscv64-64b-pcrel.s
21

Add a test using a non-SHF_ALLOC section.

This revision is now accepted and ready to land.Jun 14 2022, 12:30 PM
compnerd marked an inline comment as done.Jun 14 2022, 2:13 PM
This revision was landed with ongoing or failed builds.Jun 14 2022, 2:39 PM
This revision was automatically updated to reflect the committed changes.
craig.topper added a comment.EditedJun 29 2022, 6:41 PM

It appears that this commit has prevented test/DebugInfo/Generic/accel-table-hash-collisions.ll from completing when the llc invocation is using a riscv triple.

llvm-dwarfdebug prints an endless stream of

Data 49 [                                                                  
  Atom[0]: Error extracting the value                                      
]                                                                          
Data 50 [                                                                  
  Atom[0]: Error extracting the value                                      
]                                                                          
Data 51 [                                                                  
  Atom[0]: Error extracting the value                                      
]                                                                          
Data 52 [                                                                  
  Atom[0]: Error extracting the value                                      
]                                                                          
Data 53 [                                                                  
  Atom[0]: Error extracting the value                                      
]

with numbers that just keep increasing

Maybe because a bunch of R_RISCV_ADD32 and R_RISCV_SUB32 relocations ends up in the .rela.apple_names section?

It appears that this commit has prevented test/DebugInfo/Generic/accel-table-hash-collisions.ll from completing when the llc invocation is using a riscv triple.

llvm-dwarfdebug prints an endless stream of

Data 49 [                                                                  
  Atom[0]: Error extracting the value                                      
]                                                                          
Data 50 [                                                                  
  Atom[0]: Error extracting the value                                      
]                                                                          
Data 51 [                                                                  
  Atom[0]: Error extracting the value                                      
]                                                                          
Data 52 [                                                                  
  Atom[0]: Error extracting the value                                      
]                                                                          
Data 53 [                                                                  
  Atom[0]: Error extracting the value                                      
]

with numbers that just keep increasing

Maybe because a bunch of R_RISCV_ADD32 and R_RISCV_SUB32 relocations ends up in the .rela.apple_names section?

A similar failure happens with llvm/test/DebugInfo/Generic/cross-cu-inlining.ll but for .apple_types section

It appears that this commit has prevented test/DebugInfo/Generic/accel-table-hash-collisions.ll from completing when the llc invocation is using a riscv triple.

llvm-dwarfdebug prints an endless stream of

Data 49 [                                                                  
  Atom[0]: Error extracting the value                                      
]                                                                          
Data 50 [                                                                  
  Atom[0]: Error extracting the value                                      
]                                                                          
Data 51 [                                                                  
  Atom[0]: Error extracting the value                                      
]                                                                          
Data 52 [                                                                  
  Atom[0]: Error extracting the value                                      
]                                                                          
Data 53 [                                                                  
  Atom[0]: Error extracting the value                                      
]

with numbers that just keep increasing

Maybe because a bunch of R_RISCV_ADD32 and R_RISCV_SUB32 relocations ends up in the .rela.apple_names section?

A similar failure happens with llvm/test/DebugInfo/Generic/cross-cu-inlining.ll but for .apple_types section

I am testing adding a hack: S.getName() == ".apple_names" || S.getName() == ".apple_types";

I am checking why they are not metadata.