[RISCV] Support .option relax and .option norelax
This extends the .option support from D45864 to enable/disable the relax
feature flag from D44886
During parsing of the relax/norelax directives, the RISCV::FeatureRelax
feature bits of the SubtargetInfo stored in the AsmParser are updated
appropriately to reflect whether relaxation is currently enabled in the
parser. When an instruction is parsed, the parser checks if relaxation is
currently enabled and if so, gets a handle to the AsmBackend and sets the
ForceRelocs flag. The AsmBackend uses a combination of the original
RISCV::FeatureRelax feature bits set by e.g -mattr=+/-relax and the
ForceRelocs flag to determine whether to emit relocations for symbol and
branch diffs. Diff relocations should therefore only not be emitted if the
relax flag was not set on the command line and no instruction was ever parsed
in a section with relaxation enabled to ensure correct diffs are emitted.
Differential Revision: https://reviews.llvm.org/D46423
Patch by Lewis Revill.
llvm-svn: 346655
diff --git a/llvm/test/CodeGen/RISCV/option-relax.ll b/llvm/test/CodeGen/RISCV/option-relax.ll
new file mode 100644
index 0000000..2629699
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/option-relax.ll
@@ -0,0 +1,16 @@
+; RUN: llc -mtriple=riscv32 -mattr=-relax -filetype=obj < %s \
+; RUN: | llvm-objdump -d -r - | FileCheck %s
+
+; This test demonstrates that .option relax has no effect on codegen
+; when emitting an ELF directly.
+
+declare i32 @foo(i32)
+
+define i32 @bar(i32 %a) nounwind {
+; CHECK-LABEL: bar:
+; CHECK: R_RISCV_CALL
+; CHECK-NOT: R_RISCV_RELAX
+ tail call void asm sideeffect ".option relax", ""()
+ %1 = call i32 @foo(i32 %a)
+ ret i32 %1
+}