Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,14 @@ bool RISCVELFTargetObjectFile::isConstantInSmallSection(
MCSection *RISCVELFTargetObjectFile::getSectionForConstant(
const DataLayout &DL, SectionKind Kind, const Constant *C,
Align &Alignment) const {

// The large code model has to put constant pools close to the program, so we
// put them in the .text section. Large code model doesn't support PIC, so
// there should be no dynamic relocations that would require `.data.rel.ro`
// (which could be too far away anyway).
if (TM->getCodeModel() == CodeModel::Large)
return TextSection;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any reason to expect that .text is with +-2GB of a function in an arbitrary section. The large code model has no limit on the amount of code you're allowed to include in a program. If you need to ensure distance, you need to emit the constant pool into the same section as the function.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have addressed this, I'm not sure very well - I added a const Function * parameter because we don't have the function's section when emitConstantPool is called. This allows us to call into the section resolution logic for the function itself.


if (C && isConstantInSmallSection(DL, C)) {
if (Kind.isMergeableConst4())
return SmallROData4Section;
Expand Down
87 changes: 87 additions & 0 deletions llvm/test/CodeGen/RISCV/large-codemodel-sections.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
; RUN: llc -mtriple=riscv64 -mattr=+f,+zfh -target-abi=lp64f -code-model=large -verify-machineinstrs < %s \
; RUN: -filetype=obj -o - | llvm-readobj -r - \
; RUN: | FileCheck %s -check-prefix=RV64I
; RUN: llc -mtriple=riscv64 -mattr=+zfinx,+zhinx -target-abi=lp64 -code-model=large -verify-machineinstrs < %s \
; RUN: -filetype=obj -o - | llvm-readobj -r - \
; RUN: | FileCheck %s -check-prefix=RV64I


;; This tests that we are lowering large code model constants into `.text`
;; constant pools, so that accessing them is close to `.text`, rather than
;; far away in `.data`. The other choices are `.rodata` and `.data.rel.ro`,
;; both of which may not be close enough to `.text` to be referenced.
;;
;; The test uses `readobj` to check that there are relocations against the
;; `.text` section for these addresses. This is not compatible with PIC,
;; just like the rest of the large code model.

; RV64I: Section (3) .rela.text {
; RV64I-NEXT: R_RISCV_64 G 0x0
; RV64I-NEXT: R_RISCV_64 addr 0x0
; RV64I-NEXT: R_RISCV_64 W 0x0
; RV64I-NEXT: R_RISCV_64 X 0x0

; Check lowering of globals
@G = global i32 0
define i32 @lower_global(i32 %a) nounwind {
%1 = load volatile i32, ptr @G
ret i32 %1
}

; Check lowering of blockaddresses
@addr = global ptr null
define void @lower_blockaddress() nounwind {
store volatile ptr blockaddress(@lower_blockaddress, %block), ptr @addr
ret void

block:
unreachable
}

; Check lowering of blockaddress that forces a displacement to be added
define signext i32 @lower_blockaddress_displ(i32 signext %w) nounwind {
entry:
%x = alloca ptr, align 8
store ptr blockaddress(@lower_blockaddress_displ, %test_block), ptr %x, align 8
%cmp = icmp sgt i32 %w, 100
br i1 %cmp, label %if.then, label %if.end

if.then:
%addr = load ptr, ptr %x, align 8
br label %indirectgoto

if.end:
br label %return

test_block:
br label %return

return:
%retval = phi i32 [ 3, %if.end ], [ 4, %test_block ]
ret i32 %retval

indirectgoto:
indirectbr ptr %addr, [ label %test_block ]
}

; Check lowering of constantpools
define float @lower_constantpool(float %a) nounwind {
%1 = fadd float %a, 1.000244140625
ret float %1
}

; Check lowering of extern_weaks
@W = extern_weak global i32

define i32 @lower_extern_weak(i32 %a) nounwind {
%1 = load volatile i32, ptr @W
ret i32 %1
}

@X = global half 1.5

define half @lower_global_half(half %a) nounwind {
%b = load half, ptr @X
%1 = fadd half %a, %b
ret half %1
}