[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/fixups-relax-diff.ll b/llvm/test/CodeGen/RISCV/fixups-relax-diff.ll
new file mode 100644
index 0000000..d574a8a
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/fixups-relax-diff.ll
@@ -0,0 +1,20 @@
+; RUN: llc -filetype=obj -mtriple=riscv32 -mattr=+relax %s -o - \
+; RUN:     | llvm-readobj -r | FileCheck -check-prefix=RELAX %s
+; RUN: llc -filetype=obj -mtriple=riscv32 -mattr=-relax %s -o - \
+; RUN:     | llvm-readobj -r | FileCheck -check-prefix=NORELAX %s
+
+; This test checks that a diff inserted via inline assembly only causes
+; relocations when relaxation is enabled. This isn't an assembly test
+; as the assembler takes a different path through LLVM, which is
+; already covered by the fixups-expr.s test.
+
+define i32 @main() {
+entry:
+  %retval = alloca i32, align 4
+  store i32 0, i32* %retval, align 4
+  ; RELAX: R_RISCV_ADD64 b
+  ; RELAX: R_RISCV_SUB64 a
+  ; NORELAX-NOT: R_RISCV
+  call void asm sideeffect "a:\0Ab:\0A.dword b-a", ""()
+  ret i32 0
+}
diff --git a/llvm/test/CodeGen/RISCV/option-norelax.ll b/llvm/test/CodeGen/RISCV/option-norelax.ll
new file mode 100644
index 0000000..ad2b324
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/option-norelax.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 norelax 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: R_RISCV_RELAX
+  tail call void asm sideeffect ".option norelax", ""()
+  %1 = call i32 @foo(i32 %a)
+  ret i32 %1
+}
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
+}
diff --git a/llvm/test/MC/RISCV/option-invalid.s b/llvm/test/MC/RISCV/option-invalid.s
index ec9e8e0..904a50c 100644
--- a/llvm/test/MC/RISCV/option-invalid.s
+++ b/llvm/test/MC/RISCV/option-invalid.s
@@ -13,5 +13,5 @@
 # CHECK: error: unexpected token, expected end of statement
 .option rvc foo
 
-# CHECK: warning: unknown option, expected 'rvc' or 'norvc'
+# CHECK: warning: unknown option, expected 'rvc', 'norvc', 'relax' or 'norelax'
 .option bar
diff --git a/llvm/test/MC/RISCV/option-relax.s b/llvm/test/MC/RISCV/option-relax.s
new file mode 100644
index 0000000..82ec24b
--- /dev/null
+++ b/llvm/test/MC/RISCV/option-relax.s
@@ -0,0 +1,66 @@
+# RUN: llvm-mc -triple riscv32 < %s \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 < %s \
+# RUN:     | llvm-readobj -r | FileCheck -check-prefix=CHECK-RELOC %s
+
+# RUN: llvm-mc -triple riscv64 < %s \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 < %s \
+# RUN:     | llvm-readobj -r | FileCheck -check-prefix=CHECK-RELOC %s
+
+# Check .option relax causes R_RISCV_RELAX to be emitted, and .option
+# norelax suppresses it. Also check that if .option relax was enabled
+# at any point and an instruction may have been relaxed, diff & branch
+# relocations are emitted to ensure correct codegen. See
+# linker-relaxation.s and fixups-expr.s for behaviour of the relax
+# attribute.
+
+.L1:
+.option norelax
+# CHECK-INST: .option norelax
+
+# CHECK-INST: call foo
+# CHECK-RELOC: R_RISCV_CALL foo 0x0
+# CHECK-RELOC-NOT: R_RISCV_RELAX foo 0x0
+call foo
+
+# CHECK-RELOC-NEXT: R_RISCV_ADD64
+# CHECK-RELOC-NEXT: R_RISCV_SUB64
+.dword .L2-.L1
+# CHECK-RELOC-NEXT: R_RISCV_JAL
+jal zero, .L1
+# CHECK-RELOC-NEXT: R_RISCV_BRANCH
+beq s1, s1, .L1
+
+.L2:
+.option relax
+# CHECK-INST: .option relax
+
+# CHECK-INST: call bar
+# CHECK-RELOC-NEXT: R_RISCV_CALL bar 0x0
+# CHECK-RELOC-NEXT: R_RISCV_RELAX bar 0x0
+call bar
+
+# CHECK-RELOC-NEXT: R_RISCV_ADD64
+# CHECK-RELOC-NEXT: R_RISCV_SUB64
+.dword .L2-.L1
+# CHECK-RELOC-NEXT: R_RISCV_JAL
+jal zero, .L1
+# CHECK-RELOC-NEXT: R_RISCV_BRANCH
+beq s1, s1, .L1
+
+.option norelax
+# CHECK-INST: .option norelax
+
+# CHECK-INST: call baz
+# CHECK-RELOC-NEXT: R_RISCV_CALL baz 0x0
+# CHECK-RELOC-NOT: R_RISCV_RELAX baz 0x0
+call baz
+
+# CHECK-RELOC-NEXT: R_RISCV_ADD64
+# CHECK-RELOC-NEXT: R_RISCV_SUB64
+.dword .L2-.L1
+# CHECK-RELOC-NEXT: R_RISCV_JAL
+jal zero, .L1
+# CHECK-RELOC-NEXT: R_RISCV_BRANCH
+beq s1, s1, .L1