Skip to the content.

LLVM 中的 riscv-sextw-removal Pass 分析

该Pass对应的代码快照:https://github.com/llvm/llvm-project/blob/3e7dad22f111b9256e79dcb9cdb1c21ff0fd73dc/llvm/lib/Target/RISCV/RISCVSExtWRemoval.cpp

对应的Testcase: https://github.com/llvm/llvm-project/blob/3e7dad22f111b9256e79dcb9cdb1c21ff0fd73dc/llvm/test/CodeGen/RISCV/sextw-removal.ll

该Pass用于移除RV64中多余的sext.w指令(即setx.w a, b),根据b寄存器的def情况,分以下几种情况(isSignExtendedW):

  1. 如果b的高63:32位与第31位相同,则sext.w指令可以省去,包括以下指令(isSignExtendingOpW):
    • 包括ADDIW b, c, imm等计算低32位然后进行扩展的指令
    • SRAI b, c, uimm且uimm >= 32(保证符号位第63位被移动到了第31位及以下,因此63:31的值全相同)
    • SRLI b, c, uimm且uimm > 32(保证63:31全为0)
    • ADDI b, c, imm且c为x0寄存器(因此b的值为imm做符号扩展,63:31的值全为imm的符号位的值)
    • ANDI b, c, imm且imm在[0x0, 0x7FF]范围(保证c和imm做按位与时高63:31位全为0)
    • ORI b, c, imm且imm在[0x800, 0xFFF]范围(保证c和imm做按位或时高63:31位全为1)
    • COPY b, c且c为x0寄存器时,高63:31位全为0
  2. 如果b是一条mv指令(COPY b, c)且不满足1中的情况,则分以下几种情况:
    • c是参数且属性是sign-extention,则满足条件
    • c是返回值且其BitWidth <= 32且是sign-extension或者BitWith < 32且是zero-extension,则满足条件
    • 否则递归判断c的情况
  3. 如果是BCLRI|BINVI|BSETI b, c, imm指令且imm>=31,或者为REM b, c, d, ANDI|ORI|XORI b, c, imm,则递归判断其c寄存器的定义
    • REM b, c, d 如果c是32-bit,则b也一定是
  4. 如果是REMU|AND|OR|XOR|ANDN|ORN|XNOR|MAX|MAXU|MIN|MINU|PseudoCCMOVGPR|PHI等指令,则递归判断其输入操作数是否都是sign-extension,如果是则b也是sigen-extension,则满足条件
  5. 如果是SLLI b, c, imm且imm >= 32或者ADDI|ADD|LD|LWU|MUL|SUB指令,且所有use都只是用低31:0位(hasAllWUsers),则可以将其改为w形式的指令,从而使其高63:31位为符号扩展所得,从而满足条件。

Def的使用情况(hasAllWUsers)分如下几种情况: