通用操作码¶
注意
此文档尚未完全涵盖向量。许多标量/整数/浮点运算也可以处理向量。
常量¶
G_IMPLICIT_DEF¶
未定义的值。
%0:_(s32) = G_IMPLICIT_DEF
G_CONSTANT¶
整数常量。
%0:_(s32) = G_CONSTANT i32 1
G_FCONSTANT¶
浮点常量。
%0:_(s32) = G_FCONSTANT float 1.0
G_FRAME_INDEX¶
栈帧中对象的地址。
%1:_(p0) = G_FRAME_INDEX %stack.0.ptr0
G_GLOBAL_VALUE¶
全局值的地址。
%0(p0) = G_GLOBAL_VALUE @var_local
G_PTRAUTH_GLOBAL_VALUE¶
全局值的带符号地址。操作数:要签名的地址(指针),密钥(32 位立即数),用于地址区分的地址(如果不需要则为零)和额外的区分符(64 位立即数)。
%0:_(p0) = G_PTRAUTH_GLOBAL_VALUE %1:_(p0), s32, %2:_(p0), s64
G_BLOCK_ADDR¶
基本块的地址。
%0:_(p0) = G_BLOCK_ADDR blockaddress(@test_blockaddress, %ir-block.block)
G_CONSTANT_POOL¶
常量池中对象的地址。
%0:_(p0) = G_CONSTANT_POOL %const.0
整数扩展和截断¶
G_ANYEXT¶
扩展操作的底层标量类型,高位未指定。
%1:_(s32) = G_ANYEXT %0:_(s16)
G_SEXT¶
符号扩展操作的底层标量类型,将符号位复制到新创建的空间中。
%1:_(s32) = G_SEXT %0:_(s16)
G_SEXT_INREG¶
从任意位位置符号扩展值,将符号位复制到其上方的所有位。这等效于带有适当移位量的 shl + ashr 对。$sz 是一个立即数(MachineOperand::isImm() 返回 true),允许目标具有某些合法的位宽,而其他位宽则被降低。如果目标具有比组成移位更便宜的符号扩展指令,则此操作码特别有用,因为优化器能够做出有关是否更好地保留 G_SEXT_INREG 或将其降低并优化各个移位的决策。
%1:_(s32) = G_SEXT_INREG %0:_(s32), 16
G_ZEXT¶
零扩展操作的底层标量类型,在新创建的空间中放置零位。
%1:_(s32) = G_ZEXT %0:_(s16)
G_TRUNC¶
截断操作的底层标量类型。这对于标量类型等效于 G_EXTRACT,但对向量按元素起作用。
%1:_(s16) = G_TRUNC %0:_(s32)
类型转换¶
G_INTTOPTR¶
将整数转换为指针。
%1:_(p0) = G_INTTOPTR %0:_(s32)
G_PTRTOINT¶
将指针转换为整数。
%1:_(s32) = G_PTRTOINT %0:_(p0)
G_BITCAST¶
将值重新解释为新的类型。这通常在不更改任何位的情况下完成,但由于LLVM-IR Bitcast 指令定义中的细微差别,情况并非总是如此。允许在大小相同但地址空间不同的指针之间进行位转换。
%1:_(s64) = G_BITCAST %0:_(<2 x s32>)
G_ADDRSPACE_CAST¶
将指向某个地址空间的指针转换为指向另一个地址空间的指针。
%1:_(p1) = G_ADDRSPACE_CAST %0:_(p0)
注意
‘addrspacecast .. to’ 指令 没有提及如果转换根本无效(即如果地址空间是不相交的)会发生什么。
标量运算¶
G_EXTRACT¶
提取指定大小的寄存器,从索引给定的块开始。在选择寄存器组后,这几乎肯定会被映射到子寄存器 COPY。
%3:_(s32) = G_EXTRACT %2:_(s64), 32
G_INSERT¶
在指定的位索引处将较小的寄存器插入较大的寄存器中。
%2:_(s64) = G_INSERT %0:(_s64), %1:_(s32), 0
G_MERGE_VALUES¶
将多个相同大小的寄存器连接成一个更宽的寄存器。输入操作数始终从最低位到最高位排序
%0:(s32) = G_MERGE_VALUES %bits_0_7:(s8), %bits_8_15:(s8),
%bits_16_23:(s8), %bits_24_31:(s8)
G_UNMERGE_VALUES¶
提取指定大小的多个寄存器,从索引给定的块开始。在选择寄存器组后,这几乎肯定会被映射到子寄存器 COPY。输出操作数始终从最低位到最高位排序
%bits_0_7:(s8), %bits_8_15:(s8),
%bits_16_23:(s8), %bits_24_31:(s8) = G_UNMERGE_VALUES %0:(s32)
G_BSWAP¶
反转标量中字节的顺序。
%1:_(s32) = G_BSWAP %0:_(s32)
G_BITREVERSE¶
反转标量中位的顺序。
%1:_(s32) = G_BITREVERSE %0:_(s32)
G_SBFX, G_UBFX¶
从寄存器中提取一系列位。
源操作数是如下所示的寄存器
源
提取的最低有效位
提取的宽度
最低有效位 (lsb) 和宽度操作数的范围为
0 <= lsb < lsb + width <= source bitwidth, where all values are unsigned
G_SBFX 对结果进行符号扩展,而 G_UBFX 对结果进行零扩展。
; Extract 5 bits starting at bit 1 from %x and store them in %a.
; Sign-extend the result.
;
; Example:
; %x = 0...0000[10110]1 ---> %a = 1...111111[10110]
%lsb_one = G_CONSTANT i32 1
%width_five = G_CONSTANT i32 5
%a:_(s32) = G_SBFX %x, %lsb_one, %width_five
; Extract 3 bits starting at bit 2 from %x and store them in %b. Zero-extend
; the result.
;
; Example:
; %x = 1...11111[100]11 ---> %b = 0...00000[100]
%lsb_two = G_CONSTANT i32 2
%width_three = G_CONSTANT i32 3
%b:_(s32) = G_UBFX %x, %lsb_two, %width_three
整数运算¶
G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR, G_SDIV, G_UDIV, G_SREM, G_UREM¶
这些都对标量执行各自的整数算术运算。
%dst:_(s32) = G_ADD %src0:_(s32), %src1:_(s32)
以上示例将 %src1 加到 %src0 并将结果存储在 %dst 中。
G_SDIVREM, G_UDIVREM¶
执行整数除法和余数运算,从而产生两个结果。
%div:_(s32), %rem:_(s32) = G_SDIVREM %0:_(s32), %1:_(s32)
G_SADDSAT, G_UADDSAT, G_SSUBSAT, G_USUBSAT, G_SSHLSAT, G_USHLSAT¶
带饱和的带符号和无符号加法、减法和左移。
%2:_(s32) = G_SADDSAT %0:_(s32), %1:_(s32)
G_SHL, G_LSHR, G_ASHR¶
将标量的位左移或右移,插入零(对于 G_ASHR 则为符号位)。
G_ROTR, G_ROTL¶
向右 (G_ROTR) 或向左 (G_ROTL) 旋转位。
G_ICMP¶
执行整数比较,产生非零(真)或零(假)。真值是 1、~0U 还是其他一些非零值取决于目标。
G_SCMP¶
执行带符号的三路整数比较,生成 -1(小于)、0(等于)或 1(大于)。
%5:_(s32) = G_SCMP %6, %2
G_UCMP¶
执行无符号的三路整数比较,生成 -1(小于)、0(等于)或 1(大于)。
%7:_(s32) = G_UCMP %2, %6
G_SELECT¶
根据零/非零值在两个值之间进行选择。
%5:_(s32) = G_SELECT %4(s1), %6, %2
G_PTR_ADD¶
将标量偏移量(以可寻址单元为单位)添加到指针。可寻址单元通常为字节,但不同目标之间可能有所不同。
%1:_(p0) = G_PTR_ADD %0:_(p0), %1:_(s32)
注意
目前没有树内目标使用此功能,其可寻址单元不等于 8 位。
G_PTRMASK¶
将指针的任意位掩码清零。掩码类型必须是整数,并且所有操作数的向量元素数量必须匹配。这对应于 i_intr_llvm_ptrmask。
%2:_(p0) = G_PTRMASK %0, %1
G_SMIN, G_SMAX, G_UMIN, G_UMAX¶
获取两个值的最小值/最大值。
%5:_(s32) = G_SMIN %6, %2
G_ABS¶
获取带符号整数的绝对值。最小负值的绝对值(例如 8 位值 0x80)定义为其自身。
%1:_(s32) = G_ABS %0
G_UADDO, G_SADDO, G_USUBO, G_SSUBO, G_SMULO, G_UMULO¶
执行请求的算术运算,除了正常的计算结果外,还会生成进位输出。
%3:_(s32), %4:_(s1) = G_UADDO %0, %1
G_UADDE, G_SADDE, G_USUBE, G_SSUBE¶
执行请求的算术运算,除了正常的输入外,还会使用进位输入。除了正常的计算结果外,还会生成进位输出。
%4:_(s32), %5:_(s1) = G_UADDE %0, %1, %3:_(s1)
G_UMULH, G_SMULH¶
将两个数字乘以输入位宽的两倍(无符号或有符号),并返回结果的高半部分。
%3:_(s32) = G_UMULH %0, %1
G_CTLZ, G_CTTZ, G_CTPOP¶
计算前导零、尾随零或设置位的数量。
%2:_(s33) = G_CTLZ_ZERO_UNDEF %1
%2:_(s33) = G_CTTZ_ZERO_UNDEF %1
%2:_(s33) = G_CTPOP %1
G_CTLZ_ZERO_UNDEF, G_CTTZ_ZERO_UNDEF¶
计算前导零或尾随零。如果值为零,则结果未定义。
%2:_(s33) = G_CTLZ_ZERO_UNDEF %1
%2:_(s33) = G_CTTZ_ZERO_UNDEF %1
浮点运算¶
G_FCMP¶
执行浮点比较,生成非零(真)或零(假)。真值是 1、~0U 还是其他非零值,取决于目标。
G_FNEG¶
浮点取反。
G_FPEXT¶
将浮点值转换为更大的类型。
G_FPTRUNC¶
将浮点值转换为更窄的类型。
G_FPTOSI, G_FPTOUI, G_SITOFP, G_UITOFP¶
在整数和浮点之间转换。
G_FABS¶
获取浮点值的绝对值。
G_FCOPYSIGN¶
复制第一个操作数的值,并将符号位替换为第二个操作数的符号位。
G_FCANONICALIZE¶
G_IS_FPCLASS¶
测试第一个操作数(必须是浮点标量或向量)是否具有第二个操作数指定的浮点类。返回非零(真)或零(假)。真值是 1、~0U 还是其他非零值,取决于目标。如果第一个操作数是向量,则返回值是相同长度的向量。
G_FMINNUM¶
对两个值执行浮点最小值运算。
如果单个输入是 NaN(信号或静默),则返回非 NaN 输入。
(FMINNUM 0.0, -0.0) 的返回值可以是 0.0 或 -0.0。
G_FMAXNUM¶
对两个值执行浮点最大值运算。
如果单个输入是 NaN(信号或静默),则返回非 NaN 输入。
(FMAXNUM 0.0, -0.0) 的返回值可以是 0.0 或 -0.0。
G_FMINNUM_IEEE¶
对两个值执行浮点最小值运算,遵循 IEEE-754 定义。这在处理信号 NaN 时与 FMINNUM 不同。
如果一个输入是信号 NaN,则返回静默 NaN。这与 IEEE-754 2008 年的 minnum/maxnum 对信号 NaN 的处理方式相匹配(与 2019 年不同)。
这些将 -0 视为小于 +0,这与 IEEE-754 2019 年的 minimumNumber/maximumNumber 的行为相匹配(在 2008 年未指定)。
G_FMAXNUM_IEEE¶
对两个值执行浮点最大值运算,遵循 IEEE-754 定义。这在处理信号 NaN 时与 FMAXNUM 不同。
如果一个输入是信号 NaN,则返回静默 NaN。这与 IEEE-754 2008 年的 minnum/maxnum 对信号 NaN 的处理方式相匹配(与 2019 年不同)。
这些将 -0 视为小于 +0,这与 IEEE-754 2019 年的 minimumNumber/maximumNumber 的行为相匹配(在 2008 年未指定)。
G_FMINIMUM¶
NaN 传播最小值,还将 -0.0 视为小于 0.0。虽然 FMINNUM_IEEE 遵循 IEEE 754-2008 语义,但 FMINIMUM 遵循 IEEE 754-2019 语义。
G_FMAXIMUM¶
NaN 传播最大值,还将 -0.0 视为小于 0.0。虽然 FMAXNUM_IEEE 遵循 IEEE 754-2008 语义,但 FMAXIMUM 遵循 IEEE 754-2019 语义。
G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FREM¶
执行指定的浮点算术运算。
G_FMA¶
执行融合乘加运算(即没有中间舍入步骤)。
G_FMAD¶
执行非融合乘加运算(即有中间舍入步骤)。
G_FPOW¶
将第一个操作数提升到第二个操作数的幂。
G_FEXP, G_FEXP2¶
计算以 e 为底或以 2 为底的值的指数。
G_FLOG, G_FLOG2, G_FLOG10¶
分别计算以 e 为底、以 2 为底或以 10 为底的对数。
G_FCEIL, G_FSQRT, G_FFLOOR, G_FRINT, G_FNEARBYINT¶
这些对应于同名的标准 C 函数。
G_FCOS, G_FSIN, G_FTAN, G_FACOS, G_FASIN, G_FATAN, G_FCOSH, G_FSINH, G_FTANH¶
这些对应于同名的标准 C 三角函数。
G_INTRINSIC_TRUNC¶
返回舍入到不大于操作数的最近整数的操作数。
G_INTRINSIC_ROUND¶
返回舍入到最近整数的操作数。
G_LROUND, G_LLROUND¶
返回舍入到远离零的最近整数的源操作数。
有关行为的详细信息,请参阅 LLVM LangRef 中的“llvm.lround.*'
”条目。
%rounded_32:_(s32) = G_LROUND %round_me:_(s64)
%rounded_64:_(s64) = G_LLROUND %round_me:_(s64)
向量特定操作¶
G_VSCALE¶
将运行时 vscale
的值乘以源操作数中的值放入目标寄存器。这在确定向量中实际运行时元素数量时很有用。
%0:_(s32) = G_VSCALE 4
G_INSERT_SUBVECTOR¶
将第二个源向量插入第一个源向量。索引操作数表示在第一个源向量中应插入第二个源向量的起始索引。
索引必须是第二个源向量的最小向量长度的常数倍数。如果向量是可扩展的,则索引首先乘以运行时缩放因子。插入源向量中的索引必须是该向量的有效索引。如果无法静态确定此条件,但在运行时为假,则结果向量未定义。
%2:_(<vscale x 4 x i64>) = G_INSERT_SUBVECTOR %0:_(<vscale x 4 x i64>), %1:_(<vscale x 2 x i64>), 0
G_EXTRACT_SUBVECTOR¶
从源向量中提取目标类型的向量。索引操作数表示从源向量中提取子向量的起始索引。
索引必须是源向量的最小向量长度的常数倍数。如果源向量是可扩展向量,则索引首先乘以运行时缩放因子。从源向量中提取的索引必须是该向量的有效索引。如果无法静态确定此条件,但在运行时为假,则结果向量未定义。
%3:_(<vscale x 4 x i64>) = G_EXTRACT_SUBVECTOR %2:_(<vscale x 8 x i64>), 2
G_CONCAT_VECTORS¶
连接两个向量以形成更长的向量。
G_BUILD_VECTOR, G_BUILD_VECTOR_TRUNC¶
从多个标量寄存器创建向量。不执行隐式转换(即结果元素类型必须与所有源操作数相同)。
_TRUNC 版本将较大的操作数类型截断以适合目标向量元素类型。
G_INSERT_VECTOR_ELT¶
将元素插入向量。
G_EXTRACT_VECTOR_ELT¶
从向量中提取元素。
G_SHUFFLE_VECTOR¶
连接两个向量,并根据掩码操作数对元素进行重新排序。掩码操作数应为与 IR shufflevector 指令对应的掩码完全匹配的 IR 常量。
G_SPLAT_VECTOR¶
创建一个所有元素都来自源操作数的标量的向量。
操作数的类型必须等于或大于向量元素类型。如果操作数大于向量元素类型,则标量将隐式截断为向量元素类型。
G_VECTOR_COMPRESS¶
给定一个输入向量、一个掩码向量和一个直通向量,连续地将所有选定的(即,其中 mask[i] = true)输入通道放置到输出向量中。输出中的所有剩余通道都取自直通向量,它可能是未定义的。
向量归约操作¶
这些操作表示水平向量归约,产生一个标量结果。
G_VECREDUCE_SEQ_FADD, G_VECREDUCE_SEQ_FMUL¶
SEQ 变体按顺序执行归约。第一个操作数是初始标量累加器值,第二个操作数是要归约的向量。
G_VECREDUCE_FADD, G_VECREDUCE_FMUL¶
这些归约是宽松的变体,可以以任何顺序归约元素。
G_VECREDUCE_FMAX, G_VECREDUCE_FMIN, G_VECREDUCE_FMAXIMUM, G_VECREDUCE_FMINIMUM¶
FMIN/FMAX/FMINIMUM/FMAXIMUM 节点可以有标志,用于 NaN/NoNaN 变体。
整数/按位归约¶
G_VECREDUCE_ADD
G_VECREDUCE_MUL
G_VECREDUCE_AND
G_VECREDUCE_OR
G_VECREDUCE_XOR
G_VECREDUCE_SMAX
G_VECREDUCE_SMIN
G_VECREDUCE_UMAX
G_VECREDUCE_UMIN
整数归约的结果类型可能大于向量元素类型。但是,归约使用向量元素类型执行,最高位的值未指定。
内存操作¶
G_LOAD, G_SEXTLOAD, G_ZEXTLOAD¶
通用加载。除了显式操作数外,还期望一个 MachineMemOperand。如果结果大小大于内存大小,则高位分别为未定义、符号扩展或零扩展。
如果结果是向量类型,则只有 G_LOAD 有效。如果结果大于内存大小,则高元素未定义(即,这不是每个元素的向量 anyextload)。
与 SelectionDAG 不同,原子加载使用与常规加载相同的操作码表示。G_LOAD、G_SEXTLOAD 和 G_ZEXTLOAD 都可能具有原子内存操作数。
G_INDEXED_LOAD¶
通用索引加载。将 GEP 与加载结合起来。$newaddr 设置为 $base + $offset。如果 $am 为 0(后索引),则从 $base 加载值;如果 $am 为 1(前索引),则从 $newaddr 加载值。
G_INDEXED_SEXTLOAD¶
与 G_INDEXED_LOAD 相同,只是执行的加载是符号扩展,与 G_SEXTLOAD 相同。
G_INDEXED_ZEXTLOAD¶
与 G_INDEXED_LOAD 相同,只是执行的加载是零扩展,与 G_ZEXTLOAD 相同。
G_STORE¶
通用存储。除了显式操作数外,还期望一个 MachineMemOperand。如果存储的值大小大于内存大小,则高位将隐式截断。如果这是一个向量存储,则高元素将被丢弃(即,这不会像每个通道的向量一样工作,截断存储)。
G_INDEXED_STORE¶
将存储与 GEP 结合起来。有关索引行为,请参阅 G_INDEXED_LOAD 的说明。
G_ATOMIC_CMPXCHG_WITH_SUCCESS¶
具有内部成功检查的通用原子 cmpxchg。除了显式操作数外,还期望一个 MachineMemOperand。
G_ATOMIC_CMPXCHG¶
通用原子 cmpxchg。除了显式操作数外,还期望一个 MachineMemOperand。
G_ATOMICRMW_XCHG, G_ATOMICRMW_ADD, G_ATOMICRMW_SUB, G_ATOMICRMW_AND, G_ATOMICRMW_NAND, G_ATOMICRMW_OR, G_ATOMICRMW_XOR, G_ATOMICRMW_MAX, G_ATOMICRMW_MIN, G_ATOMICRMW_UMAX, G_ATOMICRMW_UMIN, G_ATOMICRMW_FADD, G_ATOMICRMW_FSUB, G_ATOMICRMW_FMAX, G_ATOMICRMW_FMIN¶
通用 atomicrmw。除了显式操作数外,还期望一个 MachineMemOperand。
G_FENCE¶
通用 fence。第一个操作数是内存排序。第二个操作数是同步范围。
有关更多详细信息,请参阅 LLVM LangRef 中的“fence'
”指令条目。
G_MEMCPY¶
通用 memcpy。除了显式操作数外,还期望两个分别覆盖存储和加载的 MachineMemOperands。
G_MEMCPY_INLINE¶
通用内联 memcpy。与 G_MEMCPY 类似,但保证此版本不会作为对外部函数的调用进行降低。当前,大小操作数需要计算为常量(而不是立即数),尽管当 llvm.memcpy.inline 被教导支持动态大小后,这预计会发生变化。
G_MEMMOVE¶
通用 memmove。类似于 G_MEMCPY,但允许源内存范围和目标内存范围重叠。
G_MEMSET¶
通用 memset。除了显式操作数外,还期望一个 MachineMemOperand。
G_BZERO¶
通用 bzero。除了显式操作数外,还期望一个 MachineMemOperand。
控制流¶
G_PHI¶
实现表示函数的 SSA 图中的 φ 节点。
%dst(s8) = G_PHI %src1(s8), %bb.<id1>, %src2(s8), %bb.<id2>
G_BR¶
无条件分支
G_BR %bb.<id>
G_BRCOND¶
条件分支
G_BRCOND %condition, %basicblock.<id>
G_BRINDIRECT¶
间接分支
G_BRINDIRECT %src(p0)
G_BRJT¶
跳转到跳转表项的间接分支
G_BRJT %ptr(p0), %jti, %idx(s64)
G_JUMP_TABLE¶
生成一个指向由源操作数指定的跳转表的地址的指针。源操作数是跳转表索引。G_JUMP_TABLE 可以与 G_BRJT 一起使用,以支持使用 GlobalISel 的跳转表代码生成。
%dst:_(p0) = G_JUMP_TABLE %jump-table.0
上面的示例生成一个指向源跳转表索引的指针。
G_INVOKE_REGION_START¶
一个标记指令,充当可能抛出异常的代码区域的伪终止符。作为一个终止符,它可以防止在诸如合法化之类的过程中在其后插入代码。这是必要的,因为对异常抛出例程的调用不会返回,因此在抛出后,必须位于可执行路径上的任何代码都不能放置。
G_INTRINSIC, G_INTRINSIC_CONVERGENT¶
调用没有副作用的内联函数。
_CONVERGENT 变体对应于标记为convergent的 LLVM IR 内联函数。
注意
与 SelectionDAG 不同,没有 _VOID 变体。这两种都允许具有零个、一个或多个结果。
G_INTRINSIC_W_SIDE_EFFECTS, G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS¶
调用被认为具有未知副作用的内联函数,因此不能跨其他具有副作用的指令重新排序。
_CONVERGENT 变体对应于标记为convergent的 LLVM IR 内联函数。
注意
与 SelectionDAG 不同,没有 _VOID 变体。这两种都允许具有零个、一个或多个结果。
G_TRAP, G_DEBUGTRAP, G_UBSANTRAP¶
表示llvm.trap、llvm.debugtrap和llvm.ubsantrap,它们生成目标相关的陷阱指令。
G_TRAP
G_DEBUGTRAP
G_UBSANTRAP 12
可变参数¶
G_VASTART¶
注意
我在撰写本文时没有找到此指令的文档。
G_VAARG¶
注意
我在撰写本文时没有找到此指令的文档。
其他操作¶
G_DYN_STACKALLOC¶
动态地将栈指针重新对齐到指定的大小和对齐方式。对齐值为0或1表示没有特定对齐方式。
%8:_(p0) = G_DYN_STACKALLOC %7(s64), 32
优化提示¶
这些指令不对应于任何目标指令。它们充当各种合并的提示。
G_ASSERT_SEXT, G_ASSERT_ZEXT¶
这表示寄存器的内容先前已从较小的类型扩展而来。
较小的类型使用立即数操作数表示。对于标量,这是整个较小类型的宽度。对于向量,这是较小元素类型的宽度。
%x_was_zexted:_(s32) = G_ASSERT_ZEXT %x(s32), 16
%y_was_zexted:_(<2 x s32>) = G_ASSERT_ZEXT %y(<2 x s32>), 16
%z_was_sexted:_(s32) = G_ASSERT_SEXT %z(s32), 8
G_ASSERT_SEXT 和 G_ASSERT_ZEXT 就像复制一样,尽管有一些限制。
源寄存器和目标寄存器必须
是虚拟的
属于同一个寄存器类
属于同一个寄存器组
始终可以安全地
查看源寄存器
用源寄存器替换目标寄存器
其他¶
G_CONSTANT_FOLD_BARRIER¶
此操作用作不透明屏障,以防止常量折叠。组合和其他转换不应该查看此屏障。这些操作没有其他语义,如果目标选择,可以安全地消除。