【问题标题】:Does LLVM make an exception in its type rules for integer constants?LLVM 在其整数常量的类型规则中是否有例外?
【发布时间】:2022-01-25 08:54:47
【问题描述】:

我正试图弄清楚 LLVM 中类型的确切规则。据我了解,一般规则是操作符,例如add 必须接受两个 T 类型的操作数,并返回一个 T 类型的结果。但是,整数常量似乎是一个例外。

根据https://llvm.org/docs/LangRef.html#simple-constants

标准整数(如“4”)是整数类型的常量。

“整数”这个词链接到的地方

整数类型是一种非常简单的类型,它只是为所需的整数类型指定任意位宽。可以指定从 1 位到 223(约 800 万)的任意位宽。

所以它没有说明给定常量最终的整数类型宽度。

查看 LLVM 源代码,它包含一个名为 APInt、任意精度整数、https://llvm.org/doxygen/classllvm_1_1APInt.html 的类,这似乎表明整数常量存储为任意精度。

对 clang 的一些实验产生了这个指令:

store i128 -1844674407370955161510, i128* %3, align 16, !tbaa !3

它确实有一个 128 位的整数常量,没有任何 C 表示其类型所需的特殊后缀。

但整数常量也可以是算术运算的操作数。

这是否意味着完整的类型规则类似于'运算符必须采用 T 类型的操作数,并返回 T 类型的结果,除非其中一个操作数是整数常量,在这种情况下它不会需要遵守那个规则吗?

编辑:好的,进一步深入了解解析器的作用......

LLLexer.cpp 在我正在查看的版本的第 1121 行,这似乎是它对整数常量令牌进行词法分析的地方:

  // If the next character is a '.', then it is a fp value, otherwise its
  // integer.
  if (CurPtr[0] != '.') {
    if (TokStart[0] == '0' && TokStart[1] == 'x')
      return Lex0x();
    APSIntVal = APSInt(StringRef(TokStart, CurPtr - TokStart));
    return lltok::APSInt;
  }

所以它创建了一个没有附加位宽的APSInt(任意精度有符号整数)。

【问题讨论】:

    标签: integer llvm


    【解决方案1】:

    不,不例外。

    获取常量整数的唯一方法是调用get()/getTrue()/... 中的一个ConstantInt 函数,您会注意到它们要么采用具有显式位宽的类型,要么有一个隐式类型(IIRC bool 是唯一的例子,但我可能忘记了一些东西)。

    【讨论】:

    • 对。但是,如何使用汇编语法将常量整数作为一串数字提供,而不指示位宽?
    • 因为操作中已经隐含了位宽。毕竟,您不能将 i32 位值与 64 位常量相加。
    【解决方案2】:

    根据 IRC 上的 jrtc27,所有操作数都必须具有为操作指定的类型,因此常量操作数被认为具有该类型。

    【讨论】:

      猜你喜欢
      • 2016-10-16
      • 1970-01-01
      • 1970-01-01
      • 2013-01-21
      • 1970-01-01
      • 2012-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多