1
2.. _gmir-opcodes:
3
4Generic Opcodes
5===============
6
7.. contents::
8   :local:
9
10.. note::
11
12  This documentation does not yet fully account for vectors. Many of the
13  scalar/integer/floating-point operations can also take vectors.
14
15Constants
16---------
17
18G_IMPLICIT_DEF
19^^^^^^^^^^^^^^
20
21An undefined value.
22
23.. code-block:: none
24
25  %0:_(s32) = G_IMPLICIT_DEF
26
27G_CONSTANT
28^^^^^^^^^^
29
30An integer constant.
31
32.. code-block:: none
33
34  %0:_(s32) = G_CONSTANT i32 1
35
36G_FCONSTANT
37^^^^^^^^^^^
38
39A floating point constant.
40
41.. code-block:: none
42
43  %0:_(s32) = G_FCONSTANT float 1.0
44
45G_FRAME_INDEX
46^^^^^^^^^^^^^
47
48The address of an object in the stack frame.
49
50.. code-block:: none
51
52  %1:_(p0) = G_FRAME_INDEX %stack.0.ptr0
53
54G_GLOBAL_VALUE
55^^^^^^^^^^^^^^
56
57The address of a global value.
58
59.. code-block:: none
60
61  %0(p0) = G_GLOBAL_VALUE @var_local
62
63G_BLOCK_ADDR
64^^^^^^^^^^^^
65
66The address of a basic block.
67
68.. code-block:: none
69
70  %0:_(p0) = G_BLOCK_ADDR blockaddress(@test_blockaddress, %ir-block.block)
71
72Integer Extension and Truncation
73--------------------------------
74
75G_ANYEXT
76^^^^^^^^
77
78Extend the underlying scalar type of an operation, leaving the high bits
79unspecified.
80
81.. code-block:: none
82
83  %1:_(s32) = G_ANYEXT %0:_(s16)
84
85G_SEXT
86^^^^^^
87
88Sign extend the underlying scalar type of an operation, copying the sign bit
89into the newly-created space.
90
91.. code-block:: none
92
93  %1:_(s32) = G_SEXT %0:_(s16)
94
95G_SEXT_INREG
96^^^^^^^^^^^^
97
98Sign extend the value from an arbitrary bit position, copying the sign bit
99into all bits above it. This is equivalent to a shl + ashr pair with an
100appropriate shift amount. $sz is an immediate (MachineOperand::isImm()
101returns true) to allow targets to have some bitwidths legal and others
102lowered. This opcode is particularly useful if the target has sign-extension
103instructions that are cheaper than the constituent shifts as the optimizer is
104able to make decisions on whether it's better to hang on to the G_SEXT_INREG
105or to lower it and optimize the individual shifts.
106
107.. code-block:: none
108
109  %1:_(s32) = G_SEXT_INREG %0:_(s32), 16
110
111G_ZEXT
112^^^^^^
113
114Zero extend the underlying scalar type of an operation, putting zero bits
115into the newly-created space.
116
117.. code-block:: none
118
119  %1:_(s32) = G_ZEXT %0:_(s16)
120
121G_TRUNC
122^^^^^^^
123
124Truncate the underlying scalar type of an operation. This is equivalent to
125G_EXTRACT for scalar types, but acts elementwise on vectors.
126
127.. code-block:: none
128
129  %1:_(s16) = G_TRUNC %0:_(s32)
130
131Type Conversions
132----------------
133
134G_INTTOPTR
135^^^^^^^^^^
136
137Convert an integer to a pointer.
138
139.. code-block:: none
140
141  %1:_(p0) = G_INTTOPTR %0:_(s32)
142
143G_PTRTOINT
144^^^^^^^^^^
145
146Convert a pointer to an integer.
147
148.. code-block:: none
149
150  %1:_(s32) = G_PTRTOINT %0:_(p0)
151
152G_BITCAST
153^^^^^^^^^
154
155Reinterpret a value as a new type. This is usually done without
156changing any bits but this is not always the case due a subtlety in the
157definition of the :ref:`LLVM-IR Bitcast Instruction <i_bitcast>`. It
158is allowed to bitcast between pointers with the same size, but
159different address spaces.
160
161.. code-block:: none
162
163  %1:_(s64) = G_BITCAST %0:_(<2 x s32>)
164
165G_ADDRSPACE_CAST
166^^^^^^^^^^^^^^^^
167
168Convert a pointer to an address space to a pointer to another address space.
169
170.. code-block:: none
171
172  %1:_(p1) = G_ADDRSPACE_CAST %0:_(p0)
173
174.. caution::
175
176  :ref:`i_addrspacecast` doesn't mention what happens if the cast is simply
177  invalid (i.e. if the address spaces are disjoint).
178
179Scalar Operations
180-----------------
181
182G_EXTRACT
183^^^^^^^^^
184
185Extract a register of the specified size, starting from the block given by
186index. This will almost certainly be mapped to sub-register COPYs after
187register banks have been selected.
188
189.. code-block:: none
190
191  %3:_(s32) = G_EXTRACT %2:_(s64), 32
192
193G_INSERT
194^^^^^^^^
195
196Insert a smaller register into a larger one at the specified bit-index.
197
198.. code-block:: none
199
200  %2:_(s64) = G_INSERT %0:(_s64), %1:_(s32), 0
201
202G_MERGE_VALUES
203^^^^^^^^^^^^^^
204
205Concatenate multiple registers of the same size into a wider register.
206The input operands are always ordered from lowest bits to highest:
207
208.. code-block:: none
209
210  %0:(s32) = G_MERGE_VALUES %bits_0_7:(s8), %bits_8_15:(s8),
211                            %bits_16_23:(s8), %bits_24_31:(s8)
212
213G_UNMERGE_VALUES
214^^^^^^^^^^^^^^^^
215
216Extract multiple registers of the specified size, starting from blocks given by
217indexes. This will almost certainly be mapped to sub-register COPYs after
218register banks have been selected.
219The output operands are always ordered from lowest bits to highest:
220
221.. code-block:: none
222
223  %bits_0_7:(s8), %bits_8_15:(s8),
224      %bits_16_23:(s8), %bits_24_31:(s8) = G_UNMERGE_VALUES %0:(s32)
225
226G_BSWAP
227^^^^^^^
228
229Reverse the order of the bytes in a scalar.
230
231.. code-block:: none
232
233  %1:_(s32) = G_BSWAP %0:_(s32)
234
235G_BITREVERSE
236^^^^^^^^^^^^
237
238Reverse the order of the bits in a scalar.
239
240.. code-block:: none
241
242  %1:_(s32) = G_BITREVERSE %0:_(s32)
243
244G_SBFX, G_UBFX
245^^^^^^^^^^^^^^
246
247Extract a range of bits from a register.
248
249The source operands are registers as follows:
250
251- Source
252- The least-significant bit for the extraction
253- The width of the extraction
254
255G_SBFX sign-extends the result, while G_UBFX zero-extends the result.
256
257.. code-block:: none
258
259  ; Extract 5 bits starting at bit 1 from %x and store them in %a.
260  ; Sign-extend the result.
261  ;
262  ; Example:
263  ; %x = 0...0000[10110]1 ---> %a = 1...111111[10110]
264  %lsb_one = G_CONSTANT i32 1
265  %width_five = G_CONSTANT i32 5
266  %a:_(s32) = G_SBFX %x, %lsb_one, %width_five
267
268  ; Extract 3 bits starting at bit 2 from %x and store them in %b. Zero-extend
269  ; the result.
270  ;
271  ; Example:
272  ; %x = 1...11111[100]11 ---> %b = 0...00000[100]
273  %lsb_two = G_CONSTANT i32 2
274  %width_three = G_CONSTANT i32 3
275  %b:_(s32) = G_UBFX %x, %lsb_two, %width_three
276
277Integer Operations
278-------------------
279
280G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR, G_SDIV, G_UDIV, G_SREM, G_UREM
281^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
282
283These each perform their respective integer arithmetic on a scalar.
284
285.. code-block:: none
286
287  %2:_(s32) = G_ADD %0:_(s32), %1:_(s32)
288
289G_SDIVREM, G_UDIVREM
290^^^^^^^^^^^^^^^^^^^^
291
292Perform integer division and remainder thereby producing two results.
293
294.. code-block:: none
295
296  %div:_(s32), %rem:_(s32) = G_SDIVREM %0:_(s32), %1:_(s32)
297
298G_SADDSAT, G_UADDSAT, G_SSUBSAT, G_USUBSAT, G_SSHLSAT, G_USHLSAT
299^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
300
301Signed and unsigned addition, subtraction and left shift with saturation.
302
303.. code-block:: none
304
305  %2:_(s32) = G_SADDSAT %0:_(s32), %1:_(s32)
306
307G_SHL, G_LSHR, G_ASHR
308^^^^^^^^^^^^^^^^^^^^^
309
310Shift the bits of a scalar left or right inserting zeros (sign-bit for G_ASHR).
311
312G_ROTR, G_ROTL
313^^^^^^^^^^^^^^
314
315Rotate the bits right (G_ROTR) or left (G_ROTL).
316
317G_ICMP
318^^^^^^
319
320Perform integer comparison producing non-zero (true) or zero (false). It's
321target specific whether a true value is 1, ~0U, or some other non-zero value.
322
323G_SELECT
324^^^^^^^^
325
326Select between two values depending on a zero/non-zero value.
327
328.. code-block:: none
329
330  %5:_(s32) = G_SELECT %4(s1), %6, %2
331
332G_PTR_ADD
333^^^^^^^^^
334
335Add a scalar offset in addressible units to a pointer. Addressible units are
336typically bytes but this may vary between targets.
337
338.. code-block:: none
339
340  %1:_(p0) = G_PTR_ADD %0:_(p0), %1:_(s32)
341
342.. caution::
343
344  There are currently no in-tree targets that use this with addressable units
345  not equal to 8 bit.
346
347G_PTRMASK
348^^^^^^^^^^
349
350Zero out an arbitrary mask of bits of a pointer. The mask type must be
351an integer, and the number of vector elements must match for all
352operands. This corresponds to `i_intr_llvm_ptrmask`.
353
354.. code-block:: none
355
356  %2:_(p0) = G_PTRMASK %0, %1
357
358G_SMIN, G_SMAX, G_UMIN, G_UMAX
359^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
360
361Take the minimum/maximum of two values.
362
363.. code-block:: none
364
365  %5:_(s32) = G_SMIN %6, %2
366
367G_ABS
368^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
369
370Take the absolute value of a signed integer. The absolute value of the minimum
371negative value (e.g. the 8-bit value `0x80`) is defined to be itself.
372
373.. code-block:: none
374
375  %1:_(s32) = G_ABS %0
376
377G_UADDO, G_SADDO, G_USUBO, G_SSUBO, G_SMULO, G_UMULO
378^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
379
380Perform the requested arithmetic and produce a carry output in addition to the
381normal result.
382
383.. code-block:: none
384
385  %3:_(s32), %4:_(s1) = G_UADDO %0, %1
386
387G_UADDE, G_SADDE, G_USUBE, G_SSUBE
388^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
389
390Perform the requested arithmetic and consume a carry input in addition to the
391normal input. Also produce a carry output in addition to the normal result.
392
393.. code-block:: none
394
395  %4:_(s32), %5:_(s1) = G_UADDE %0, %1, %3:_(s1)
396
397G_UMULH, G_SMULH
398^^^^^^^^^^^^^^^^
399
400Multiply two numbers at twice the incoming bit width (signed) and return
401the high half of the result.
402
403.. code-block:: none
404
405  %3:_(s32) = G_UMULH %0, %1
406
407G_CTLZ, G_CTTZ, G_CTPOP
408^^^^^^^^^^^^^^^^^^^^^^^
409
410Count leading zeros, trailing zeros, or number of set bits.
411
412.. code-block:: none
413
414  %2:_(s33) = G_CTLZ_ZERO_UNDEF %1
415  %2:_(s33) = G_CTTZ_ZERO_UNDEF %1
416  %2:_(s33) = G_CTPOP %1
417
418G_CTLZ_ZERO_UNDEF, G_CTTZ_ZERO_UNDEF
419^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
420
421Count leading zeros or trailing zeros. If the value is zero then the result is
422undefined.
423
424.. code-block:: none
425
426  %2:_(s33) = G_CTLZ_ZERO_UNDEF %1
427  %2:_(s33) = G_CTTZ_ZERO_UNDEF %1
428
429Floating Point Operations
430-------------------------
431
432G_FCMP
433^^^^^^
434
435Perform floating point comparison producing non-zero (true) or zero
436(false). It's target specific whether a true value is 1, ~0U, or some other
437non-zero value.
438
439G_FNEG
440^^^^^^
441
442Floating point negation.
443
444G_FPEXT
445^^^^^^^
446
447Convert a floating point value to a larger type.
448
449G_FPTRUNC
450^^^^^^^^^
451
452Convert a floating point value to a narrower type.
453
454G_FPTOSI, G_FPTOUI, G_SITOFP, G_UITOFP
455^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
456
457Convert between integer and floating point.
458
459G_FABS
460^^^^^^
461
462Take the absolute value of a floating point value.
463
464G_FCOPYSIGN
465^^^^^^^^^^^
466
467Copy the value of the first operand, replacing the sign bit with that of the
468second operand.
469
470G_FCANONICALIZE
471^^^^^^^^^^^^^^^
472
473See :ref:`i_intr_llvm_canonicalize`.
474
475G_FMINNUM
476^^^^^^^^^
477
478Perform floating-point minimum on two values.
479
480In the case where a single input is a NaN (either signaling or quiet),
481the non-NaN input is returned.
482
483The return value of (FMINNUM 0.0, -0.0) could be either 0.0 or -0.0.
484
485G_FMAXNUM
486^^^^^^^^^
487
488Perform floating-point maximum on two values.
489
490In the case where a single input is a NaN (either signaling or quiet),
491the non-NaN input is returned.
492
493The return value of (FMAXNUM 0.0, -0.0) could be either 0.0 or -0.0.
494
495G_FMINNUM_IEEE
496^^^^^^^^^^^^^^
497
498Perform floating-point minimum on two values, following the IEEE-754 2008
499definition. This differs from FMINNUM in the handling of signaling NaNs. If one
500input is a signaling NaN, returns a quiet NaN.
501
502G_FMAXNUM_IEEE
503^^^^^^^^^^^^^^
504
505Perform floating-point maximum on two values, following the IEEE-754 2008
506definition. This differs from FMAXNUM in the handling of signaling NaNs. If one
507input is a signaling NaN, returns a quiet NaN.
508
509G_FMINIMUM
510^^^^^^^^^^
511
512NaN-propagating minimum that also treat -0.0 as less than 0.0. While
513FMINNUM_IEEE follow IEEE 754-2008 semantics, FMINIMUM follows IEEE 754-2018
514draft semantics.
515
516G_FMAXIMUM
517^^^^^^^^^^
518
519NaN-propagating maximum that also treat -0.0 as less than 0.0. While
520FMAXNUM_IEEE follow IEEE 754-2008 semantics, FMAXIMUM follows IEEE 754-2018
521draft semantics.
522
523G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FREM
524^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
525
526Perform the specified floating point arithmetic.
527
528G_FMA
529^^^^^
530
531Perform a fused multiply add (i.e. without the intermediate rounding step).
532
533G_FMAD
534^^^^^^
535
536Perform a non-fused multiply add (i.e. with the intermediate rounding step).
537
538G_FPOW
539^^^^^^
540
541Raise the first operand to the power of the second.
542
543G_FEXP, G_FEXP2
544^^^^^^^^^^^^^^^
545
546Calculate the base-e or base-2 exponential of a value
547
548G_FLOG, G_FLOG2, G_FLOG10
549^^^^^^^^^^^^^^^^^^^^^^^^^
550
551Calculate the base-e, base-2, or base-10 respectively.
552
553G_FCEIL, G_FCOS, G_FSIN, G_FSQRT, G_FFLOOR, G_FRINT, G_FNEARBYINT
554^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
555
556These correspond to the standard C functions of the same name.
557
558G_INTRINSIC_TRUNC
559^^^^^^^^^^^^^^^^^
560
561Returns the operand rounded to the nearest integer not larger in magnitude than the operand.
562
563G_INTRINSIC_ROUND
564^^^^^^^^^^^^^^^^^
565
566Returns the operand rounded to the nearest integer.
567
568Vector Specific Operations
569--------------------------
570
571G_CONCAT_VECTORS
572^^^^^^^^^^^^^^^^
573
574Concatenate two vectors to form a longer vector.
575
576G_BUILD_VECTOR, G_BUILD_VECTOR_TRUNC
577^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
578
579Create a vector from multiple scalar registers. No implicit
580conversion is performed (i.e. the result element type must be the
581same as all source operands)
582
583The _TRUNC version truncates the larger operand types to fit the
584destination vector elt type.
585
586G_INSERT_VECTOR_ELT
587^^^^^^^^^^^^^^^^^^^
588
589Insert an element into a vector
590
591G_EXTRACT_VECTOR_ELT
592^^^^^^^^^^^^^^^^^^^^
593
594Extract an element from a vector
595
596G_SHUFFLE_VECTOR
597^^^^^^^^^^^^^^^^
598
599Concatenate two vectors and shuffle the elements according to the mask operand.
600The mask operand should be an IR Constant which exactly matches the
601corresponding mask for the IR shufflevector instruction.
602
603Vector Reduction Operations
604---------------------------
605
606These operations represent horizontal vector reduction, producing a scalar result.
607
608G_VECREDUCE_SEQ_FADD, G_VECREDUCE_SEQ_FMUL
609^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
610
611The SEQ variants perform reductions in sequential order. The first operand is
612an initial scalar accumulator value, and the second operand is the vector to reduce.
613
614G_VECREDUCE_FADD, G_VECREDUCE_FMUL
615^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
616
617These reductions are relaxed variants which may reduce the elements in any order.
618
619G_VECREDUCE_FMAX, G_VECREDUCE_FMIN
620^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
621
622FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
623
624
625Integer/bitwise reductions
626^^^^^^^^^^^^^^^^^^^^^^^^^^
627
628* G_VECREDUCE_ADD
629* G_VECREDUCE_MUL
630* G_VECREDUCE_AND
631* G_VECREDUCE_OR
632* G_VECREDUCE_XOR
633* G_VECREDUCE_SMAX
634* G_VECREDUCE_SMIN
635* G_VECREDUCE_UMAX
636* G_VECREDUCE_UMIN
637
638Integer reductions may have a result type larger than the vector element type.
639However, the reduction is performed using the vector element type and the value
640in the top bits is unspecified.
641
642Memory Operations
643-----------------
644
645G_LOAD, G_SEXTLOAD, G_ZEXTLOAD
646^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
647
648Generic load. Expects a MachineMemOperand in addition to explicit
649operands. If the result size is larger than the memory size, the
650high bits are undefined, sign-extended, or zero-extended respectively.
651
652Only G_LOAD is valid if the result is a vector type. If the result is larger
653than the memory size, the high elements are undefined (i.e. this is not a
654per-element, vector anyextload)
655
656G_INDEXED_LOAD
657^^^^^^^^^^^^^^
658
659Generic indexed load. Combines a GEP with a load. $newaddr is set to $base + $offset.
660If $am is 0 (post-indexed), then the value is loaded from $base; if $am is 1 (pre-indexed)
661then the value is loaded from $newaddr.
662
663G_INDEXED_SEXTLOAD
664^^^^^^^^^^^^^^^^^^
665
666Same as G_INDEXED_LOAD except that the load performed is sign-extending, as with G_SEXTLOAD.
667
668G_INDEXED_ZEXTLOAD
669^^^^^^^^^^^^^^^^^^
670
671Same as G_INDEXED_LOAD except that the load performed is zero-extending, as with G_ZEXTLOAD.
672
673G_STORE
674^^^^^^^
675
676Generic store. Expects a MachineMemOperand in addition to explicit
677operands. If the stored value size is greater than the memory size,
678the high bits are implicitly truncated. If this is a vector store, the
679high elements are discarded (i.e. this does not function as a per-lane
680vector, truncating store)
681
682G_INDEXED_STORE
683^^^^^^^^^^^^^^^
684
685Combines a store with a GEP. See description of G_INDEXED_LOAD for indexing behaviour.
686
687G_ATOMIC_CMPXCHG_WITH_SUCCESS
688^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
689
690Generic atomic cmpxchg with internal success check. Expects a
691MachineMemOperand in addition to explicit operands.
692
693G_ATOMIC_CMPXCHG
694^^^^^^^^^^^^^^^^
695
696Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
697operands.
698
699G_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
700^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
701
702Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
703operands.
704
705G_FENCE
706^^^^^^^
707
708.. caution::
709
710  I couldn't find any documentation on this at the time of writing.
711
712Control Flow
713------------
714
715G_PHI
716^^^^^
717
718Implement the φ node in the SSA graph representing the function.
719
720.. code-block:: none
721
722  %1(s8) = G_PHI %7(s8), %bb.0, %3(s8), %bb.1
723
724G_BR
725^^^^
726
727Unconditional branch
728
729G_BRCOND
730^^^^^^^^
731
732Conditional branch
733
734G_BRINDIRECT
735^^^^^^^^^^^^
736
737Indirect branch
738
739G_BRJT
740^^^^^^
741
742Indirect branch to jump table entry
743
744G_JUMP_TABLE
745^^^^^^^^^^^^
746
747.. caution::
748
749  I found no documentation for this instruction at the time of writing.
750
751G_INTRINSIC, G_INTRINSIC_W_SIDE_EFFECTS
752^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
753
754Call an intrinsic
755
756The _W_SIDE_EFFECTS version is considered to have unknown side-effects and
757as such cannot be reordered across other side-effecting instructions.
758
759.. note::
760
761  Unlike SelectionDAG, there is no _VOID variant. Both of these are permitted
762  to have zero, one, or multiple results.
763
764Variadic Arguments
765------------------
766
767G_VASTART
768^^^^^^^^^
769
770.. caution::
771
772  I found no documentation for this instruction at the time of writing.
773
774G_VAARG
775^^^^^^^
776
777.. caution::
778
779  I found no documentation for this instruction at the time of writing.
780
781Other Operations
782----------------
783
784G_DYN_STACKALLOC
785^^^^^^^^^^^^^^^^
786
787Dynamically realigns the stack pointer to the specified size and alignment.
788An alignment value of `0` or `1` means no specific alignment.
789
790.. code-block:: none
791
792  %8:_(p0) = G_DYN_STACKALLOC %7(s64), 32
793
794Optimization Hints
795------------------
796
797These instructions do not correspond to any target instructions. They act as
798hints for various combines.
799
800G_ASSERT_SEXT, G_ASSERT_ZEXT
801^^^^^^^^^^^^^^^^^^^^^^^^^^^^
802
803This signifies that the contents of a register were previously extended from a
804smaller type.
805
806The smaller type is denoted using an immediate operand. For scalars, this is the
807width of the entire smaller type. For vectors, this is the width of the smaller
808element type.
809
810.. code-block:: none
811
812  %x_was_zexted:_(s32) = G_ASSERT_ZEXT %x(s32), 16
813  %y_was_zexted:_(<2 x s32>) = G_ASSERT_ZEXT %y(<2 x s32>), 16
814
815  %z_was_sexted:_(s32) = G_ASSERT_SEXT %z(s32), 8
816
817G_ASSERT_SEXT and G_ASSERT_ZEXT act like copies, albeit with some restrictions.
818
819The source and destination registers must
820
821- Be virtual
822- Belong to the same register class
823- Belong to the same register bank
824
825It should always be safe to
826
827- Look through the source register
828- Replace the destination register with the source register
829