Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Driver] Default enable LoongArch linker relaxation #111488

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 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
7 changes: 7 additions & 0 deletions clang/lib/Driver/ToolChains/Arch/LoongArch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,13 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D,
(!Args.hasArgNoClaim(clang::driver::options::OPT_march_EQ)))
Features.push_back("+lsx");

// -mrelax is default, unless -mno-relax is specified.
Copy link
Member

Choose a reason for hiding this comment

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

This code self explains and the comment is not necessary.

if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, true)) {
Features.push_back("+relax");
} else {
Features.push_back("-relax");
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Author

Choose a reason for hiding this comment

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

Thanks, it reminds me to check out llvm's codestandard.

std::string ArchName;
if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
ArchName = A->getValue();
Expand Down
4 changes: 2 additions & 2 deletions clang/test/Driver/loongarch-features.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// RUN: %clang --target=loongarch32 -S -emit-llvm %s -o - | FileCheck %s --check-prefix=LA32
// RUN: %clang --target=loongarch64 -S -emit-llvm %s -o - | FileCheck %s --check-prefix=LA64

// LA32: "target-features"="+32bit"
// LA64: "target-features"="+64bit,+d,+f,+lsx,+ual"
// LA32: "target-features"="+32bit,+relax"
// LA64: "target-features"="+64bit,+d,+f,+lsx,+relax,+ual"

int foo(void) {
return 3;
Expand Down
20 changes: 10 additions & 10 deletions clang/test/Driver/loongarch-march.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,39 +21,39 @@

// CC1-LOONGARCH64: "-target-cpu" "loongarch64"
// CC1-LOONGARCH64-NOT: "-target-feature"
// CC1-LOONGARCH64: "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+ual"
// CC1-LOONGARCH64: "-target-feature" "+relax" "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+ual"
// CC1-LOONGARCH64-NOT: "-target-feature"
// CC1-LOONGARCH64: "-target-abi" "lp64d"

// CC1-LA464: "-target-cpu" "la464"
// CC1-LA464-NOT: "-target-feature"
// CC1-LA464: "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+lasx" "-target-feature" "+ual"
// CC1-LA464: "-target-feature" "+relax" "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+lasx" "-target-feature" "+ual"
// CC1-LA464-NOT: "-target-feature"
// CC1-LA464: "-target-abi" "lp64d"

// CC1-LA64V1P0: "-target-cpu" "loongarch64"
// CC1-LA64V1P0-NOT: "-target-feature"
// CC1-LA64V1P0: "-target-feature" "+64bit" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+ual"
// CC1-LA64V1P0: "-target-feature" "+relax" "-target-feature" "+64bit" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+ual"
// CC1-LA64V1P0-NOT: "-target-feature"
// CC1-LA64V1P0: "-target-abi" "lp64d"

// CC1-LA64V1P1: "-target-cpu" "loongarch64"
// CC1-LA64V1P1-NOT: "-target-feature"
// CC1-LA64V1P1: "-target-feature" "+64bit" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+ual" "-target-feature" "+frecipe"
// CC1-LA64V1P1: "-target-feature" "+relax" "-target-feature" "+64bit" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+ual" "-target-feature" "+frecipe"
// CC1-LA64V1P1-NOT: "-target-feature"
// CC1-LA64V1P1: "-target-abi" "lp64d"

// CC1-LA664: "-target-cpu" "la664"
// CC1-LA664-NOT: "-target-feature"
// CC1-LA664: "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+lasx" "-target-feature" "+ual" "-target-feature" "+frecipe"
// CC1-LA664: "-target-feature" "+relax" "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+lasx" "-target-feature" "+ual" "-target-feature" "+frecipe"
// CC1-LA664-NOT: "-target-feature"
// CC1-LA664: "-target-abi" "lp64d"

// IR-LOONGARCH64: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+f,+ual"
// IR-LA464: attributes #[[#]] ={{.*}}"target-cpu"="la464" {{.*}}"target-features"="+64bit,+d,+f,+lasx,+lsx,+ual"
// IR-LA64V1P0: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+lsx,+ual"
// IR-LA64V1P1: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+frecipe,+lsx,+ual"
// IR-LA664: attributes #[[#]] ={{.*}}"target-cpu"="la664" {{.*}}"target-features"="+64bit,+d,+f,+frecipe,+lasx,+lsx,+ual"
// IR-LOONGARCH64: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+f,+relax,+ual"
// IR-LA464: attributes #[[#]] ={{.*}}"target-cpu"="la464" {{.*}}"target-features"="+64bit,+d,+f,+lasx,+lsx,+relax,+ual"
// IR-LA64V1P0: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+lsx,+relax,+ual"
// IR-LA64V1P1: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+frecipe,+lsx,+relax,+ual"
// IR-LA664: attributes #[[#]] ={{.*}}"target-cpu"="la664" {{.*}}"target-features"="+64bit,+d,+f,+frecipe,+lasx,+lsx,+relax,+ual"

int foo(void) {
return 3;
Expand Down
5 changes: 4 additions & 1 deletion lld/ELF/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,8 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
for (;;) {
bool changed = ctx.target->needsThunks
? tc.createThunks(pass, ctx.outputSections)
: ctx.arg.emachine == EM_LOONGARCH && !ctx.arg.relax
Copy link
Member

Choose a reason for hiding this comment

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

Adding ctx.arg.relax to every place is not acceptable. You could change ctx.arg.relax to be always false for loongarch, though.

Copy link
Author

Choose a reason for hiding this comment

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

Adding ctx.arg.relax to every place is not acceptable. You could change ctx.arg.relax to be always false for loongarch, though.

ctx.arg.relax is used here because we want to determine whether or not to apply relaxation based on the parameters passed at the time of linking.

Copy link
Contributor

Choose a reason for hiding this comment

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

ctx.arg.relax is used here because we want to determine whether or not to apply relaxation based on the parameters passed at the time of linking.

I don't think so. R_LARCH_ALIGN should be handled unconditionally, otherwise the code may be unaligned.

Copy link
Author

Choose a reason for hiding this comment

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

ctx.arg.relax is used here because we want to determine whether or not to apply relaxation based on the parameters passed at the time of linking.

I don't think so. R_LARCH_ALIGN should be handled unconditionally, otherwise the code may be unaligned.

Yes, it was an oversight. So for scenarios outside of align, is it necessary to determine whether or not to apply relaxation via the incoming link parameter, i.e. --relax? For example, in the relax function

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, it was an oversight. So for scenarios outside of align, is it necessary to determine whether or not to apply relaxation via the incoming link parameter, i.e. --relax? For example, in the relax function

I'm afraid it's not necessary because R_LARCH_RELAX is converted to R_NONE by function getRelExpr when --no-relax.

  case R_LARCH_RELAX:
    return ctx.arg.relax ? R_RELAX_HINT : R_NONE;
  case R_LARCH_ALIGN:
    return R_RELAX_HINT

Is it correct? @MQ-mengqing

Copy link
Author

@ywgrit ywgrit Oct 14, 2024

Choose a reason for hiding this comment

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

Yes, it was an oversight. So for scenarios outside of align, is it necessary to determine whether or not to apply relaxation via the incoming link parameter, i.e. --relax? For example, in the relax function

I'm afraid it's not necessary because R_LARCH_RELAX is converted to R_NONE by function getRelExpr when --no-relax.

  case R_LARCH_RELAX:
    return ctx.arg.relax ? R_RELAX_HINT : R_NONE;
  case R_LARCH_ALIGN:
    return R_RELAX_HINT

Is it correct? @MQ-mengqing

Thanks for the reminder, I tested both on RISCV and LoongArch, the relocation which corresponding RelExpr is R_NONE will be ignored. The changes of test files will be reverted.

? false
: ctx.target->relaxOnce(pass);
bool spilled = ctx.script->spillSections();
changed |= spilled;
Expand Down Expand Up @@ -1545,7 +1547,8 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
finalizeOrderDependentContent();
}
}
if (!ctx.arg.relocatable)
if (!ctx.arg.relocatable &&
!(ctx.arg.emachine == EM_LOONGARCH && !ctx.arg.relax))
ctx.target->finalizeRelax(pass);

if (ctx.arg.relocatable)
Expand Down
209 changes: 169 additions & 40 deletions lld/test/ELF/loongarch-relax-align.s
Original file line number Diff line number Diff line change
Expand Up @@ -6,56 +6,180 @@
# RUN: ld.lld --section-start=.text=0x10000 --section-start=.text2=0x20000 -e 0 %t.64.o -o %t.64
# RUN: ld.lld --section-start=.text=0x10000 --section-start=.text2=0x20000 -e 0 %t.32.o --no-relax -o %t.32n
# RUN: ld.lld --section-start=.text=0x10000 --section-start=.text2=0x20000 -e 0 %t.64.o --no-relax -o %t.64n
# RUN: llvm-objdump -td --no-show-raw-insn %t.32 | FileCheck %s
# RUN: llvm-objdump -td --no-show-raw-insn %t.64 | FileCheck %s
# RUN: llvm-objdump -td --no-show-raw-insn %t.32n | FileCheck %s
# RUN: llvm-objdump -td --no-show-raw-insn %t.64n | FileCheck %s
# RUN: llvm-objdump -td --no-show-raw-insn %t.32 | FileCheck %s --check-prefix=RELAX32
# RUN: llvm-objdump -td --no-show-raw-insn %t.64 | FileCheck %s --check-prefixes=RELAX64,SRELAX64
# RUN: llvm-objdump -td --no-show-raw-insn %t.32n | FileCheck %s --check-prefix=NORELAX
# RUN: llvm-objdump -td --no-show-raw-insn %t.64n | FileCheck %s --check-prefix=NORELAX

## Test the R_LARCH_ALIGN without symbol index.
# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o %t.o64.o --defsym=old=1
# RUN: ld.lld --section-start=.text=0x10000 --section-start=.text2=0x20000 -e 0 %t.o64.o -o %t.o64
# RUN: ld.lld --section-start=.text=0x10000 --section-start=.text2=0x20000 -e 0 %t.o64.o --no-relax -o %t.o64n
# RUN: llvm-objdump -td --no-show-raw-insn %t.o64 | FileCheck %s
# RUN: llvm-objdump -td --no-show-raw-insn %t.o64n | FileCheck %s
# RUN: llvm-objdump -td --no-show-raw-insn %t.o64 | FileCheck %s --check-prefixes=RELAX64,ORELAX64
# RUN: llvm-objdump -td --no-show-raw-insn %t.o64n | FileCheck %s --check-prefix=ONORELAX

## -r keeps section contents unchanged.
# RUN: ld.lld -r %t.64.o -o %t.64.r
# RUN: llvm-objdump -dr --no-show-raw-insn %t.64.r | FileCheck %s --check-prefix=CHECKR

# CHECK-DAG: {{0*}}10000 l .text {{0*}}44 .Ltext_start
# CHECK-DAG: {{0*}}10038 l .text {{0*}}0c .L1
# CHECK-DAG: {{0*}}10040 l .text {{0*}}04 .L2
# CHECK-DAG: {{0*}}20000 l .text2 {{0*}}14 .Ltext2_start

# CHECK: <.Ltext_start>:
# CHECK-NEXT: break 1
# CHECK-NEXT: break 2
# CHECK-NEXT: nop
# CHECK-NEXT: nop
# CHECK-NEXT: break 3
# CHECK-NEXT: break 4
# CHECK-NEXT: nop
# CHECK-NEXT: nop
# CHECK-NEXT: pcalau12i $a0, 0
# CHECK-NEXT: addi.{{[dw]}} $a0, $a0, 0
# CHECK-NEXT: pcalau12i $a0, 0
# CHECK-NEXT: addi.{{[dw]}} $a0, $a0, 56
# CHECK-NEXT: pcalau12i $a0, 0
# CHECK-NEXT: addi.{{[dw]}} $a0, $a0, 64
# CHECK-EMPTY:
# CHECK-NEXT: <.L1>:
# CHECK-NEXT: nop
# CHECK-NEXT: nop
# CHECK-EMPTY:
# CHECK-NEXT: <.L2>:
# CHECK-NEXT: break 5

# CHECK: <.Ltext2_start>:
# CHECK-NEXT: pcalau12i $a0, 0
# CHECK-NEXT: addi.{{[dw]}} $a0, $a0, 0
# CHECK-NEXT: nop
# CHECK-NEXT: nop
# CHECK-NEXT: break 6

# RELAX32-DAG: {{0*}}10000 l .text {{0*}}00 .Lalign_symbol
# RELAX32-DAG: {{0*}}10000 l .text {{0*}}44 .Ltext_start
# RELAX32-DAG: {{0*}}10038 l .text {{0*}}0c .L1
# RELAX32-DAG: {{0*}}10040 l .text {{0*}}04 .L2
# RELAX32-DAG: {{0*}}20000 l .text2 {{0*}}14 .Ltext2_start

# RELAX32: <.Ltext_start>:
# RELAX32-NEXT: break 1
# RELAX32-NEXT: break 2
# RELAX32-NEXT: nop
# RELAX32-NEXT: nop
# RELAX32-NEXT: break 3
# RELAX32-NEXT: break 4
# RELAX32-NEXT: nop
# RELAX32-NEXT: nop
# RELAX32-NEXT: pcalau12i $a0, 0
# RELAX32-NEXT: addi.{{[dw]}} $a0, $a0, 0
# RELAX32-NEXT: pcalau12i $a0, 0
# RELAX32-NEXT: addi.{{[dw]}} $a0, $a0, 56
# RELAX32-NEXT: pcalau12i $a0, 0
# RELAX32-NEXT: addi.{{[dw]}} $a0, $a0, 64
# RELAX32-EMPTY:
# RELAX32-NEXT: <.L1>:
# RELAX32-NEXT: nop
# RELAX32-NEXT: nop
# RELAX32-EMPTY:
# RELAX32-NEXT: <.L2>:
# RELAX32-NEXT: break 5

# RELAX32: <.Ltext2_start>:
# RELAX32-NEXT: pcalau12i $a0, 0
# RELAX32-NEXT: addi.{{[dw]}} $a0, $a0, 0
# RELAX32-NEXT: nop
# RELAX32-NEXT: nop
# RELAX32-NEXT: break 6

# NORELAX-DAG: {{0*}}10000 l .text {{0*}}00 .Lalign_symbol
# NORELAX-DAG: {{0*}}10000 l .text {{0*}}5c .Ltext_start
# NORELAX-DAG: {{0*}}1004c l .text {{0*}}10 .L1
# NORELAX-DAG: {{0*}}10058 l .text {{0*}}04 .L2
# NORELAX-DAG: {{0*}}20000 l .text2 {{0*}}18 .Ltext2_start

# NORELAX: <.Ltext_start>:
# NORELAX-NEXT: break 1
# NORELAX-NEXT: break 2
# NORELAX-NEXT: nop
# NORELAX-NEXT: nop
# NORELAX-NEXT: nop
# NORELAX-NEXT: break 3
# NORELAX-NEXT: nop
# NORELAX-NEXT: nop
# NORELAX-NEXT: nop
# NORELAX-NEXT: break 4
# NORELAX-NEXT: nop
# NORELAX-NEXT: nop
# NORELAX-NEXT: nop
# NORELAX-NEXT: pcalau12i $a0, 0
# NORELAX-NEXT: addi.{{[dw]}} $a0, $a0, 0
# NORELAX-NEXT: pcalau12i $a0, 0
# NORELAX-NEXT: addi.{{[dw]}} $a0, $a0, 76
# NORELAX-NEXT: pcalau12i $a0, 0
# NORELAX-NEXT: addi.{{[dw]}} $a0, $a0, 88
# NORELAX-EMPTY:
# NORELAX-NEXT: <.L1>:
# NORELAX-NEXT: nop
# NORELAX-NEXT: nop
# NORELAX-NEXT: nop
# NORELAX-EMPTY:
# NORELAX-NEXT: <.L2>:
# NORELAX-NEXT: break 5

# NORELAX: <.Ltext2_start>:
# NORELAX-NEXT: pcalau12i $a0, 0
# NORELAX-NEXT: addi.{{[dw]}} $a0, $a0, 0
# NORELAX-NEXT: nop
# NORELAX-NEXT: nop
# NORELAX-NEXT: nop
# NORELAX-NEXT: break 6



# ORELAX64-DAG: {{0*}}00001 l *ABS* {{0*}}00 old
# SRELAX64-DAG: {{0*}}10000 l .text {{0*}}00 .Lalign_symbol
# RELAX64-DAG: {{0*}}10000 l .text {{0*}}44 .Ltext_start
# RELAX64-DAG: {{0*}}10038 l .text {{0*}}0c .L1
# RELAX64-DAG: {{0*}}10040 l .text {{0*}}04 .L2
# RELAX64-DAG: {{0*}}20000 l .text2 {{0*}}14 .Ltext2_start

# RELAX64: <.Ltext_start>:
# RELAX64-NEXT: break 1
# RELAX64-NEXT: break 2
# RELAX64-NEXT: nop
# RELAX64-NEXT: nop
# RELAX64-NEXT: break 3
# RELAX64-NEXT: break 4
# RELAX64-NEXT: nop
# RELAX64-NEXT: nop
# RELAX64-NEXT: pcalau12i $a0, 0
# RELAX64-NEXT: addi.d $a0, $a0, 0
# RELAX64-NEXT: pcalau12i $a0, 0
# RELAX64-NEXT: addi.d $a0, $a0, 56
# RELAX64-NEXT: pcalau12i $a0, 0
# RELAX64-NEXT: addi.d $a0, $a0, 64
# RELAX64-EMPTY:
# RELAX64-NEXT: <.L1>:
# RELAX64-NEXT: nop
# RELAX64-NEXT: nop
# RELAX64-EMPTY:
# RELAX64-NEXT: <.L2>:
# RELAX64-NEXT: break 5

# RELAX64: <.Ltext2_start>:
# RELAX64-NEXT: pcalau12i $a0, 0
# RELAX64-NEXT: addi.d $a0, $a0, 0
# RELAX64-NEXT: nop
# RELAX64-NEXT: nop
# RELAX64-NEXT: break 6


# ONORELAX-DAG: {{0*}}00001 l *ABS* {{0*}}00 old
# ONORELAX-DAG: {{0*}}10000 l .text {{0*}}4c .Ltext_start
# ONORELAX-DAG: {{0*}}1003c l .text {{0*}}10 .L1
# ONORELAX-DAG: {{0*}}10048 l .text {{0*}}04 .L2
# ONORELAX-DAG: {{0*}}20000 l .text2 {{0*}}18 .Ltext2_start

# ONORELAX: <.Ltext_start>:
# ONORELAX-NEXT: break 1
# ONORELAX-NEXT: break 2
# ONORELAX-NEXT: nop
# ONORELAX-NEXT: nop
# ONORELAX-NEXT: nop
# ONORELAX-NEXT: break 3
# ONORELAX-NEXT: break 4
# ONORELAX-NEXT: nop
# ONORELAX-NEXT: nop
# ONORELAX-NEXT: pcalau12i $a0, 0
# ONORELAX-NEXT: addi.{{[dw]}} $a0, $a0, 0
# ONORELAX-NEXT: pcalau12i $a0, 0
# ONORELAX-NEXT: addi.{{[dw]}} $a0, $a0, 60
# ONORELAX-NEXT: pcalau12i $a0, 0
# ONORELAX-NEXT: addi.{{[dw]}} $a0, $a0, 72
# ONORELAX-EMPTY:
# ONORELAX-NEXT: <.L1>:
# ONORELAX-NEXT: nop
# ONORELAX-NEXT: nop
# ONORELAX-NEXT: nop
# ONORELAX-EMPTY:
# ONORELAX-NEXT: <.L2>:
# ONORELAX-NEXT: break 5

# ONORELAX: <.Ltext2_start>:
# ONORELAX-NEXT: pcalau12i $a0, 0
# ONORELAX-NEXT: addi.{{[dw]}} $a0, $a0, 0
# ONORELAX-NEXT: nop
# ONORELAX-NEXT: nop
# ONORELAX-NEXT: nop
# ONORELAX-NEXT: break 6

# CHECKR: <.Ltext2_start>:
# CHECKR-NEXT: pcalau12i $a0, 0
Expand All @@ -70,6 +194,11 @@
# CHECKR-NEXT: nop
# CHECKR-NEXT: break 6






.macro .fake_p2align_4 max=0
.ifdef old
.if \max==0
Expand Down
5 changes: 2 additions & 3 deletions lld/test/ELF/loongarch-relax-emit-relocs.s
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@
# RUN: ld.lld -r %t.64.o -o %t.64.r
# RUN: llvm-objdump -dr %t.64.r | FileCheck %s --check-prefix=CHECKR

## --no-relax should keep original relocations.
## TODO Due to R_LARCH_RELAX is not relaxed, it plays same as --relax now.
# RUN: ld.lld -Ttext=0x10000 --emit-relocs --no-relax %t.64.o -o %t.64.norelax
# RUN: llvm-objdump -dr %t.64.norelax | FileCheck %s
# RUN: llvm-objdump -dr %t.64.norelax | FileCheck %s --check-prefixes=CHECK,NORELAX

# CHECK: 00010000 <_start>:
# CHECK-NEXT: pcalau12i $a0, 0
Expand All @@ -27,6 +25,7 @@
# CHECK-NEXT: nop
# CHECK-NEXT: R_LARCH_ALIGN *ABS*+0xc
# CHECK-NEXT: nop
# NORELAX-NEXT: nop
# CHECK-NEXT: ret

# CHECKR: <_start>:
Expand Down
Loading