[lld] [RISCV] Compress unrelaxable lui when RVC attribute is present (PR #74715)
Nemanja Ivanovic via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 11 07:43:39 PST 2023
================
@@ -650,8 +650,36 @@ static void relaxHi20Lo12(const InputSection &sec, size_t i, uint64_t loc,
if (!gp)
return;
+ bool noRelaxation = false;
if (!isInt<12>(r.sym->getVA(r.addend) - gp->getVA()))
+ noRelaxation = true;
+
+ if (noRelaxation) {
+ if (r.type != R_RISCV_HI20 || !(config->eflags & EF_RISCV_RVC) ||
+ !isInt<18>(r.sym->getVA(r.addend)))
+ return;
+ // We have a HI20 reloc that fits in 18 bits but not in 12 bits
+ // and compressed instructions are enabled.
+ // Try to compress the lui to a c.lui.
+ const unsigned bits = config->wordsize * 8;
+ uint32_t rd = extractBits(read32le(sec.content().data() + r.offset), 11, 7);
+ uint32_t newInsn = 0x6001 | (rd << 7); // c.lui
+ int64_t imm = SignExtend64(r.sym->getVA(r.addend) + 0x800, bits) >> 12;
+
+ // The high immediate may be outside the range if the low needs to be
+ // negative. So the isInt<18> check above is not sufficient. Also,
+ // rd != 2 for c.lui.
+ if (rd == 2 || !isInt<6>(imm))
+ return;
+ if (imm == 0)
+ newInsn &= 0xDFFF;
+ uint16_t imm17 = extractBits(imm, 17, 17) << 12;
----------------
nemanjai wrote:
Oh, I see. That does indeed seem wrong. It should be
```
uint16_t imm17 = extractBits(imm, 5, 5) << 12;
uint16_t imm16_12 = extractBits(imm, 4, 0) << 2;
```
https://github.com/llvm/llvm-project/pull/74715
More information about the llvm-commits
mailing list