You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LLVM DAG中常量在Lowering阶段变更,如何阻止该变更?

阻止LLVM Lowering阶段DAG常量变更的方法

1. 精准禁用DAG Combine相关优化

如果常量变更是在DAG Combine阶段发生的:

  • 全局禁用(不推荐,影响性能):编译时添加命令行选项 disable-dag-combiner
  • 精细控制:修改LLVM源码DAGCombiner.cpp,找到处理AND指令或常量折叠的逻辑,添加条件跳过对i8类型-32的处理。例如:
    // 在DAG组合逻辑中添加判断
    if (Op.getOpcode() == ISD::AND) {
      SDValue ConstOp = Op.getOperand(1);
      if (ConstOp.isConstant() && ConstOp.getValueType() == MVT::i8 &&
          cast<ConstantSDNode>(ConstOp)->getSExtValue() == -32) {
        return SDValue(); // 跳过当前组合逻辑
      }
    }
    

2. 调整LegalizeDAG阶段的常量合法性规则

若变更发生在Legalize阶段,通常是目标架构对有符号常量的处理规则导致:

  • 在目标架构的XXXLegalizerInfo.cpp文件中,修改getLegality或常量合法化逻辑,标记i8类型的-32为合法常量,避免被转换为无符号形式。例如:
    // 在目标LegalizerInfo初始化中添加
    getActions().setLegal({MVT::i8, /* 对应常量-32的规则 */});
    

3. 在IR层强制保留常量形式

通过IR编码方式避免常量被自动转换:

  • 将常量定义为全局常量,而非直接使用字面量:
    @neg32_i8 = constant i8 -32
    ...
    %bf.clear = and i8 %bf.load, @neg32_i8
    
    全局常量在Lowering阶段更难被自动修改。

4. 自定义目标Lowering逻辑

针对目标架构的TargetLowering.cpp,重写LowerOperation方法,拦截AND指令并保留目标常量:

SDValue XXXTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
  switch (Op.getOpcode()) {
  case ISD::AND: {
    SDValue Op1 = Op.getOperand(1);
    if (Op1.isConstant() && Op1.getValueType() == MVT::i8 &&
        cast<ConstantSDNode>(Op1)->getSExtValue() == -32) {
      return Op; // 直接返回原指令,不做修改
    }
    // 其他正常Lower逻辑
    break;
  }
  // 其他指令处理
  }
  return TargetLowering::LowerOperation(Op, DAG);
}

提示:先通过-view-dag-combine1-dags和-view-legalize-dags确认变更发生的具体阶段,再针对性处理。

内容的提问来源于stack exchange,提问作者xiaoroubao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 02:01:14