通用操作碼

備註

本文件尚不完全包含向量。許多純量/整數/浮點數運算也可以採用向量。

常數

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

執行帶符號的 3 向整數比較,產生 -1(較小)、0(相等)或 1(較大)。

%5:_(s32) = G_SCMP %6, %2

G_UCMP

執行無符號的 3 向整數比較,產生 -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

請參閱 ‘llvm.canonicalize.*’ Intrinsic

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 定義,對兩個值執行浮點最小值運算。這與 FMINNUM 在處理信號 NaN 方面有所不同。

如果一個輸入是信號 NaN,則傳回靜默 NaN。這與 IEEE-754 2008 對信號 NaN 的 minnum/maxnum 相符(與 2019 不同)。

這些將 -0 視為小於 +0 的排序,與 IEEE-754 2019 的 minimumNumber/maximumNumber 行為相符(2008 年未指定)。

G_FMAXNUM_IEEE

依照 IEEE-754 定義,對兩個值執行浮點最大值運算。這與 FMAXNUM 在處理信號 NaN 方面有所不同。

如果一個輸入是信號 NaN,則傳回靜默 NaN。這與 IEEE-754 2008 對信號 NaN 的 minnum/maxnum 相符(與 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 版本會截斷較大的運算元類型,以符合目標向量 elt 類型。

G_INSERT_VECTOR_ELT

將元素插入向量。

G_EXTRACT_VECTOR_ELT

從向量中提取元素。

G_SHUFFLE_VECTOR

串聯兩個向量並根據遮罩運算元排列元素。遮罩運算元應為 IR 常數,與 IR shufflevector 指令的對應遮罩完全匹配。

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 詞條。

G_MEMCPY

泛型 memcpy。除了顯式操作數之外,還需要兩個分別覆蓋存儲和加載的 MachineMemOperand。

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.trapllvm.debugtrapllvm.ubsantrap,它們產生目標相關的陷阱指令。

G_TRAP
G_DEBUGTRAP
G_UBSANTRAP 12

可變參數

G_VASTART

注意

在撰寫本文時,我沒有找到關於此指令的說明文件。

G_VAARG

注意

在撰寫本文時,我沒有找到關於此指令的說明文件。

其他操作

G_DYN_STACKALLOC

動態地將堆疊指標重新對齊到指定的大小和對齊方式。對齊值 01 表示沒有特定的對齊方式。

%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

此操作用作防止常數摺疊的不透明屏障。組合和其他轉換不應查看此內容。這些沒有其他語義,如果目標選擇,則可以安全地消除。