bool RISCVMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout,
const MCFixup *Fixup) const {
- bool IsSymbolicDifference = false;
- if (const auto *MBE = dyn_cast<MCBinaryExpr>(getSubExpr())) {
- if (isa<MCBinaryExpr>(MBE->getLHS()) && isa<MCConstantExpr>(MBE->getRHS()))
- MBE = cast<MCBinaryExpr>(MBE->getLHS());
- IsSymbolicDifference = isa<MCSymbolRefExpr>(MBE->getLHS()) &&
- isa<MCSymbolRefExpr>(MBE->getRHS());
- }
+ // Explicitly drop the layout and assembler to prevent any symbolic folding in
+ // the expression handling. This is required to preserve symbolic difference
+ // expressions to emit the paired relocations.
+ if (!getSubExpr()->evaluateAsRelocatable(Res, nullptr, nullptr))
+ return false;
- // Some custom fixup types are not valid with symbol difference expressions
- if (IsSymbolicDifference) {
- switch (getKind()) {
- default:
- break;
- case VK_RISCV_LO:
- case VK_RISCV_HI:
- case VK_RISCV_PCREL_LO:
- case VK_RISCV_PCREL_HI:
- case VK_RISCV_GOT_HI:
- case VK_RISCV_TPREL_LO:
- case VK_RISCV_TPREL_HI:
- case VK_RISCV_TPREL_ADD:
- case VK_RISCV_TLS_GOT_HI:
- case VK_RISCV_TLS_GD_HI:
- return false;
- }
- }
- return getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup);
+ Res =
+ MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), getKind());
+ // Custom fixup types are not valid with symbol difference expressions.
+ return Res.getSymB() ? getKind() == VK_RISCV_None : true;
}
void RISCVMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
--- /dev/null
+# RUN: not llvm-mc -triple riscv32 -filetype obj %s -o /dev/null 2>&1 | FileCheck %s
+
+.Ltmp1:
+ .quad tls
+
+ lui a0, %hi(tls+0-.Ltmp1)
+# CHECK: :[[#@LINE-1]]:2: error: expected relocatable expression
+ lw a0, %lo(tls+0-.Ltmp1)(t0)
+# CHECK: :[[#@LINE-1]]:2: error: expected relocatable expression
+ lui a0, %tprel_hi(tls+0-.Ltmp1)
+# CHECK: :[[#@LINE-1]]:2: error: expected relocatable expression
+ add a0, a0, tp, %tprel_add(tls+0-.Ltmp1)
+# CHECK: :[[#@LINE-1]]:2: error: expected relocatable expression
+ addi a0, a0, %tprel_lo(tls+0-.Ltmp1)
+# CHECK: :[[#@LINE-1]]:2: error: expected relocatable expression
+ auipc a0, %tls_ie_pcrel_hi(tls+0-.Ltmp1)
+# CHECK: :[[#@LINE-1]]:2: error: expected relocatable expression
+ auipc a0, %tls_gd_pcrel_hi(tls+0-.Ltmp1)
+# CHECK: :[[#@LINE-1]]:2: error: expected relocatable expression
+ auipc a0, %pcrel_hi(tls-.Ltmp1)
+# CHECK: :[[#@LINE-1]]:2: error: expected relocatable expression
+ auipc a0, %got_pcrel_hi(tls-.Ltmp1)
+# CHECK: :[[#@LINE-1]]:2: error: expected relocatable expression
+ addi a0, a0, %pcrel_lo(tls-.Ltmp1)
+# CHECK: :[[#@LINE-1]]:2: error: expected relocatable expression
+
+# tail tls+32
+# tail tls-tls
+# _ :[[#@LINE-1]]:2: error: expected relocatable expression