Page MenuHomePhabricator

[llvm-mc] - Produce R_X86_64_PLT32 relocation for branches with JCC opcodes too.
ClosedPublic

Authored by grimar on Jan 16 2020, 3:42 AM.

Details

Summary

The idea is to produce R_X86_64_PLT32 instead of
R_X86_64_PC32 for branches.

It fixes https://bugs.llvm.org/show_bug.cgi?id=44397.

This patch teaches MC to do that for JCC (jump if condition is met)
instructions. The new behavior matches modern GNU as.
It is similar to D43383, which did the same for "call/jmp foo",
but missed JCC cases.

Diff Detail

Event Timeline

grimar created this revision.Jan 16 2020, 3:42 AM
Herald added a project: Restricted Project. · View Herald Transcript
MaskRay accepted this revision.EditedJan 16 2020, 11:02 AM

R_X86_64_PLT32 is a branch relocation type which means the exact address is insignificant.

  • In an executable, it can prevent the creation of a canonical PLT entry.
  • In a shared object, an R_X86_64_PC32 to a preemptible symbol is not allowed.

This can be favorable since it can enable us to use JCC_4 for tail calls.

This revision is now accepted and ready to land.Jan 16 2020, 11:02 AM
This revision was automatically updated to reflect the committed changes.

CC @hans ... there was discussion in https://bugs.llvm.org/show_bug.cgi?id=44397 about whether this is worth picking to 10.0.

MaskRay added a comment.EditedFri, Jan 24, 11:37 AM

CC @hans ... there was discussion in https://bugs.llvm.org/show_bug.cgi?id=44397 about whether this is worth picking to 10.0.

This is related to CodeGen/BranchFolding.cpp (D29856).

I think certain -Os and -Oz code with static relocation model could create such bne foo with R_X86_64_PC32. If the target is defined in a shared object, it will create a canonical PLT.
It does not hurt to include it in release/10.x but I also don't think there is a demanding need. (Non -Os/-Oz optimization levels do not trigger. -fpie-/-fpic does not trigger.)

define void @foo(i32* %a) minsize {
entry:
  %0 = load i32, i32* %a
  %cmp = icmp eq i32 %0, 0
  br i1 %cmp, label %if.then, label %if.else
if.then:
  tail call void @bar()
  br label %if.else
if.else:
  ret void
}

declare void @bar()