c++ - APInt(unsigned numBits, uint64_t val, bool isSigned = false) 中的参数 bool 有何用途?

标签 c++ llvm

我对第三个参数感到好奇,即来自 LLVM llvm/ADT/APInt.h headerAPInt(unsigned numBits, uint64_t val, bool isSigned = false) 中的 bool 值 isSigned

无论我将其设置为什么,getActiveBits()getMinSignedBits() 等函数的结果根本不会改变。

此外,如果我想获取有符号/无符号值,我可以使用 getSExtValue()getZExtValue()

isSigned 的值对他们来说也不重要。

那么什么时候 isSigned 才重要呢?

最佳答案

TL;DR: isSigned 仅对 numBits > 64 重要。

sizeof(val) 只有 64 位。想象一下,您想要将有符号值存储在大小 > 64 位的整数中。

  • 如果值为负,则所有高位必须设置为 1,因为负值通常存储为 two's complement .

  • 如果值为正,则所有高位必须设置为0

示例

假设您想要以 128 位存储 -1

持有-1uint64_t val的二进制表示是

1111111111111111111111111111111111111111111111111111111111111111

这只有 64 位,所以还剩下 64 位需要填充。如果没有 isSigned 值,就不可能知道这些位是否应该为1,从而导致-1 strong>,结果为 18446744073709551615

长解释

看看source code揭示了 isSigned 仅在某些情况下使用:

APInt(unsigned numBits, uint64_t val, bool isSigned = false)
     : BitWidth(numBits) {
   assert(BitWidth && "bitwidth too small");
   if (isSingleWord()) {
       U.VAL = val;
       clearUnusedBits();
   } else {
       initSlowCase(val, isSigned);
   }
}

根据its function header , isSingleWord

returns true if the number of bits <= 64, false otherwise.

因此该行

if (isSingleWord()) {

检查值的存储是否占用比 val 本身更多的内存。

如果numBits大于64,APInt::initSlowCase被调用:

void APInt::initSlowCase(uint64_t val, bool isSigned) {
   U.pVal = getClearedMemory(getNumWords());
   U.pVal[0] = val;
   if (isSigned && int64_t(val) < 0)
       for (unsigned i = 1; i < getNumWords(); ++i)
           U.pVal[i] = WORDTYPE_MAX;
   clearUnusedBits();
}

此函数复制 val 变量中的值并将位填充到 numBits

这是必要的,因为负值存储为二进制补码。如果设置了 isSigned 并且 val 为负值,则高字的所有位都设置为 1。

关于c++ - APInt(unsigned numBits, uint64_t val, bool isSigned = false) 中的参数 bool 有何用途?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57409882/

相关文章:

c++ - 如何在类方法中创建即时相关的静态变量?

c++ - 规范化 "Point"

c++ - 使用 qsort 对字符串进行排序不起作用

virtual-machine - LLVM中的VM在哪里?

c++ - 为什么 LLVM 中的 Expected<T> 为 Expected<T>&& 实现了两个构造函数?

xcode - Xcode 4.5 中的 llvm 4.2 中的 clang 版本是什么?

c++ - 继承单例

c++ - GCC 严格溢出

xcode - 为 macOS 构建,但链接为独立构建的目标文件

llvm - 如何将 LLVMPass long opt 命令更改为简单命令