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
189G_INSERT
190^^^^^^^^
191
192Insert a smaller register into a larger one at the specified bit-index.
193
194G_MERGE_VALUES
195^^^^^^^^^^^^^^
196
197Concatenate multiple registers of the same size into a wider register.
198The input operands are always ordered from lowest bits to highest:
199
200.. code-block:: none
201
202  %0:(s32) = G_MERGE_VALUES %bits_0_7:(s8), %bits_8_15:(s8),
203                            %bits_16_23:(s8), %bits_24_31:(s8)
204
205G_UNMERGE_VALUES
206^^^^^^^^^^^^^^^^
207
208Extract multiple registers of the specified size, starting from blocks given by
209indexes. This will almost certainly be mapped to sub-register COPYs after
210register banks have been selected.
211The output operands are always ordered from lowest bits to highest:
212
213.. code-block:: none
214
215  %bits_0_7:(s8), %bits_8_15:(s8),
216      %bits_16_23:(s8), %bits_24_31:(s8) = G_UNMERGE_VALUES %0:(s32)
217
218G_BSWAP
219^^^^^^^
220
221Reverse the order of the bytes in a scalar.
222
223.. code-block:: none
224
225  %1:_(s32) = G_BSWAP %0:_(s32)
226
227G_BITREVERSE
228^^^^^^^^^^^^
229
230Reverse the order of the bits in a scalar.
231
232.. code-block:: none
233
234  %1:_(s32) = G_BITREVERSE %0:_(s32)
235
236Integer Operations
237-------------------
238
239G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR, G_SDIV, G_UDIV, G_SREM, G_UREM
240^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
241
242These each perform their respective integer arithmetic on a scalar.
243
244.. code-block:: none
245
246  %2:_(s32) = G_ADD %0:_(s32), %1:_(s32)
247
248G_SDIVREM, G_UDIVREM
249^^^^^^^^^^^^^^^^^^^^
250
251Perform integer division and remainder thereby producing two results.
252
253.. code-block:: none
254
255  %div:_(s32), %rem:_(s32) = G_SDIVREM %0:_(s32), %1:_(s32)
256
257G_SADDSAT, G_UADDSAT, G_SSUBSAT, G_USUBSAT, G_SSHLSAT, G_USHLSAT
258^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
259
260Signed and unsigned addition, subtraction and left shift with saturation.
261
262.. code-block:: none
263
264  %2:_(s32) = G_SADDSAT %0:_(s32), %1:_(s32)
265
266G_SHL, G_LSHR, G_ASHR
267^^^^^^^^^^^^^^^^^^^^^
268
269Shift the bits of a scalar left or right inserting zeros (sign-bit for G_ASHR).
270
271G_ICMP
272^^^^^^
273
274Perform integer comparison producing non-zero (true) or zero (false). It's
275target specific whether a true value is 1, ~0U, or some other non-zero value.
276
277G_SELECT
278^^^^^^^^
279
280Select between two values depending on a zero/non-zero value.
281
282.. code-block:: none
283
284  %5:_(s32) = G_SELECT %4(s1), %6, %2
285
286G_PTR_ADD
287^^^^^^^^^
288
289Add a scalar offset in addressible units to a pointer. Addressible units are
290typically bytes but this may vary between targets.
291
292.. code-block:: none
293
294  %1:_(p0) = G_PTR_ADD %0:_(p0), %1:_(s32)
295
296.. caution::
297
298  There are currently no in-tree targets that use this with addressable units
299  not equal to 8 bit.
300
301G_PTRMASK
302^^^^^^^^^^
303
304Zero out an arbitrary mask of bits of a pointer. The mask type must be
305an integer, and the number of vector elements must match for all
306operands. This corresponds to `i_intr_llvm_ptrmask`.
307
308.. code-block:: none
309
310  %2:_(p0) = G_PTRMASK %0, %1
311
312G_SMIN, G_SMAX, G_UMIN, G_UMAX
313^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
314
315Take the minimum/maximum of two values.
316
317.. code-block:: none
318
319  %5:_(s32) = G_SMIN %6, %2
320
321G_ABS
322^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
323
324Take the absolute value of a signed integer. The absolute value of the minimum
325negative value (e.g. the 8-bit value `0x80`) is defined to be itself.
326
327.. code-block:: none
328
329  %1:_(s32) = G_ABS %0
330
331G_UADDO, G_SADDO, G_USUBO, G_SSUBO, G_SMULO, G_UMULO
332^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
333
334Perform the requested arithmetic and produce a carry output in addition to the
335normal result.
336
337.. code-block:: none
338
339  %3:_(s32), %4:_(s1) = G_UADDO %0, %1
340
341G_UADDE, G_SADDE, G_USUBE, G_SSUBE
342^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
343
344Perform the requested arithmetic and consume a carry input in addition to the
345normal input. Also produce a carry output in addition to the normal result.
346
347.. code-block:: none
348
349  %4:_(s32), %5:_(s1) = G_UADDE %0, %1, %3:_(s1)
350
351G_UMULH, G_SMULH
352^^^^^^^^^^^^^^^^
353
354Multiply two numbers at twice the incoming bit width (signed) and return
355the high half of the result.
356
357.. code-block:: none
358
359  %3:_(s32) = G_UMULH %0, %1
360
361G_CTLZ, G_CTTZ, G_CTPOP
362^^^^^^^^^^^^^^^^^^^^^^^
363
364Count leading zeros, trailing zeros, or number of set bits.
365
366.. code-block:: none
367
368  %2:_(s33) = G_CTLZ_ZERO_UNDEF %1
369  %2:_(s33) = G_CTTZ_ZERO_UNDEF %1
370  %2:_(s33) = G_CTPOP %1
371
372G_CTLZ_ZERO_UNDEF, G_CTTZ_ZERO_UNDEF
373^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
374
375Count leading zeros or trailing zeros. If the value is zero then the result is
376undefined.
377
378.. code-block:: none
379
380  %2:_(s33) = G_CTLZ_ZERO_UNDEF %1
381  %2:_(s33) = G_CTTZ_ZERO_UNDEF %1
382
383Floating Point Operations
384-------------------------
385
386G_FCMP
387^^^^^^
388
389Perform floating point comparison producing non-zero (true) or zero
390(false). It's target specific whether a true value is 1, ~0U, or some other
391non-zero value.
392
393G_FNEG
394^^^^^^
395
396Floating point negation.
397
398G_FPEXT
399^^^^^^^
400
401Convert a floating point value to a larger type.
402
403G_FPTRUNC
404^^^^^^^^^
405
406Convert a floating point value to a narrower type.
407
408G_FPTOSI, G_FPTOUI, G_SITOFP, G_UITOFP
409^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
410
411Convert between integer and floating point.
412
413G_FABS
414^^^^^^
415
416Take the absolute value of a floating point value.
417
418G_FCOPYSIGN
419^^^^^^^^^^^
420
421Copy the value of the first operand, replacing the sign bit with that of the
422second operand.
423
424G_FCANONICALIZE
425^^^^^^^^^^^^^^^
426
427See :ref:`i_intr_llvm_canonicalize`.
428
429G_FMINNUM
430^^^^^^^^^
431
432Perform floating-point minimum on two values.
433
434In the case where a single input is a NaN (either signaling or quiet),
435the non-NaN input is returned.
436
437The return value of (FMINNUM 0.0, -0.0) could be either 0.0 or -0.0.
438
439G_FMAXNUM
440^^^^^^^^^
441
442Perform floating-point maximum on two values.
443
444In the case where a single input is a NaN (either signaling or quiet),
445the non-NaN input is returned.
446
447The return value of (FMAXNUM 0.0, -0.0) could be either 0.0 or -0.0.
448
449G_FMINNUM_IEEE
450^^^^^^^^^^^^^^
451
452Perform floating-point minimum on two values, following the IEEE-754 2008
453definition. This differs from FMINNUM in the handling of signaling NaNs. If one
454input is a signaling NaN, returns a quiet NaN.
455
456G_FMAXNUM_IEEE
457^^^^^^^^^^^^^^
458
459Perform floating-point maximum on two values, following the IEEE-754 2008
460definition. This differs from FMAXNUM in the handling of signaling NaNs. If one
461input is a signaling NaN, returns a quiet NaN.
462
463G_FMINIMUM
464^^^^^^^^^^
465
466NaN-propagating minimum that also treat -0.0 as less than 0.0. While
467FMINNUM_IEEE follow IEEE 754-2008 semantics, FMINIMUM follows IEEE 754-2018
468draft semantics.
469
470G_FMAXIMUM
471^^^^^^^^^^
472
473NaN-propagating maximum that also treat -0.0 as less than 0.0. While
474FMAXNUM_IEEE follow IEEE 754-2008 semantics, FMAXIMUM follows IEEE 754-2018
475draft semantics.
476
477G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FREM
478^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
479
480Perform the specified floating point arithmetic.
481
482G_FMA
483^^^^^
484
485Perform a fused multiply add (i.e. without the intermediate rounding step).
486
487G_FMAD
488^^^^^^
489
490Perform a non-fused multiply add (i.e. with the intermediate rounding step).
491
492G_FPOW
493^^^^^^
494
495Raise the first operand to the power of the second.
496
497G_FEXP, G_FEXP2
498^^^^^^^^^^^^^^^
499
500Calculate the base-e or base-2 exponential of a value
501
502G_FLOG, G_FLOG2, G_FLOG10
503^^^^^^^^^^^^^^^^^^^^^^^^^
504
505Calculate the base-e, base-2, or base-10 respectively.
506
507G_FCEIL, G_FCOS, G_FSIN, G_FSQRT, G_FFLOOR, G_FRINT, G_FNEARBYINT
508^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
509
510These correspond to the standard C functions of the same name.
511
512G_INTRINSIC_TRUNC
513^^^^^^^^^^^^^^^^^
514
515Returns the operand rounded to the nearest integer not larger in magnitude than the operand.
516
517G_INTRINSIC_ROUND
518^^^^^^^^^^^^^^^^^
519
520Returns the operand rounded to the nearest integer.
521
522Vector Specific Operations
523--------------------------
524
525G_CONCAT_VECTORS
526^^^^^^^^^^^^^^^^
527
528Concatenate two vectors to form a longer vector.
529
530G_BUILD_VECTOR, G_BUILD_VECTOR_TRUNC
531^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
532
533Create a vector from multiple scalar registers. No implicit
534conversion is performed (i.e. the result element type must be the
535same as all source operands)
536
537The _TRUNC version truncates the larger operand types to fit the
538destination vector elt type.
539
540G_INSERT_VECTOR_ELT
541^^^^^^^^^^^^^^^^^^^
542
543Insert an element into a vector
544
545G_EXTRACT_VECTOR_ELT
546^^^^^^^^^^^^^^^^^^^^
547
548Extract an element from a vector
549
550G_SHUFFLE_VECTOR
551^^^^^^^^^^^^^^^^
552
553Concatenate two vectors and shuffle the elements according to the mask operand.
554The mask operand should be an IR Constant which exactly matches the
555corresponding mask for the IR shufflevector instruction.
556
557Vector Reduction Operations
558---------------------------
559
560These operations represent horizontal vector reduction, producing a scalar result.
561
562G_VECREDUCE_SEQ_FADD, G_VECREDUCE_SEQ_FMUL
563^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
564
565The SEQ variants perform reductions in sequential order. The first operand is
566an initial scalar accumulator value, and the second operand is the vector to reduce.
567
568G_VECREDUCE_FADD, G_VECREDUCE_FMUL
569^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
570
571These reductions are relaxed variants which may reduce the elements in any order.
572
573G_VECREDUCE_FMAX, G_VECREDUCE_FMIN
574^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
575
576FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
577
578
579Integer/bitwise reductions
580^^^^^^^^^^^^^^^^^^^^^^^^^^
581
582* G_VECREDUCE_ADD
583* G_VECREDUCE_MUL
584* G_VECREDUCE_AND
585* G_VECREDUCE_OR
586* G_VECREDUCE_XOR
587* G_VECREDUCE_SMAX
588* G_VECREDUCE_SMIN
589* G_VECREDUCE_UMAX
590* G_VECREDUCE_UMIN
591
592Integer reductions may have a result type larger than the vector element type.
593However, the reduction is performed using the vector element type and the value
594in the top bits is unspecified.
595
596Memory Operations
597-----------------
598
599G_LOAD, G_SEXTLOAD, G_ZEXTLOAD
600^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
601
602Generic load. Expects a MachineMemOperand in addition to explicit
603operands. If the result size is larger than the memory size, the
604high bits are undefined, sign-extended, or zero-extended respectively.
605
606Only G_LOAD is valid if the result is a vector type. If the result is larger
607than the memory size, the high elements are undefined (i.e. this is not a
608per-element, vector anyextload)
609
610G_INDEXED_LOAD
611^^^^^^^^^^^^^^
612
613Generic indexed load. Combines a GEP with a load. $newaddr is set to $base + $offset.
614If $am is 0 (post-indexed), then the value is loaded from $base; if $am is 1 (pre-indexed)
615then the value is loaded from $newaddr.
616
617G_INDEXED_SEXTLOAD
618^^^^^^^^^^^^^^^^^^
619
620Same as G_INDEXED_LOAD except that the load performed is sign-extending, as with G_SEXTLOAD.
621
622G_INDEXED_ZEXTLOAD
623^^^^^^^^^^^^^^^^^^
624
625Same as G_INDEXED_LOAD except that the load performed is zero-extending, as with G_ZEXTLOAD.
626
627G_STORE
628^^^^^^^
629
630Generic store. Expects a MachineMemOperand in addition to explicit
631operands. If the stored value size is greater than the memory size,
632the high bits are implicitly truncated. If this is a vector store, the
633high elements are discarded (i.e. this does not function as a per-lane
634vector, truncating store)
635
636G_INDEXED_STORE
637^^^^^^^^^^^^^^^
638
639Combines a store with a GEP. See description of G_INDEXED_LOAD for indexing behaviour.
640
641G_ATOMIC_CMPXCHG_WITH_SUCCESS
642^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
643
644Generic atomic cmpxchg with internal success check. Expects a
645MachineMemOperand in addition to explicit operands.
646
647G_ATOMIC_CMPXCHG
648^^^^^^^^^^^^^^^^
649
650Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
651operands.
652
653G_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
654^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
655
656Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
657operands.
658
659G_FENCE
660^^^^^^^
661
662.. caution::
663
664  I couldn't find any documentation on this at the time of writing.
665
666Control Flow
667------------
668
669G_PHI
670^^^^^
671
672Implement the φ node in the SSA graph representing the function.
673
674.. code-block:: none
675
676  %1(s8) = G_PHI %7(s8), %bb.0, %3(s8), %bb.1
677
678G_BR
679^^^^
680
681Unconditional branch
682
683G_BRCOND
684^^^^^^^^
685
686Conditional branch
687
688G_BRINDIRECT
689^^^^^^^^^^^^
690
691Indirect branch
692
693G_BRJT
694^^^^^^
695
696Indirect branch to jump table entry
697
698G_JUMP_TABLE
699^^^^^^^^^^^^
700
701.. caution::
702
703  I found no documentation for this instruction at the time of writing.
704
705G_INTRINSIC, G_INTRINSIC_W_SIDE_EFFECTS
706^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
707
708Call an intrinsic
709
710The _W_SIDE_EFFECTS version is considered to have unknown side-effects and
711as such cannot be reordered across other side-effecting instructions.
712
713.. note::
714
715  Unlike SelectionDAG, there is no _VOID variant. Both of these are permitted
716  to have zero, one, or multiple results.
717
718Variadic Arguments
719------------------
720
721G_VASTART
722^^^^^^^^^
723
724.. caution::
725
726  I found no documentation for this instruction at the time of writing.
727
728G_VAARG
729^^^^^^^
730
731.. caution::
732
733  I found no documentation for this instruction at the time of writing.
734
735Other Operations
736----------------
737
738G_DYN_STACKALLOC
739^^^^^^^^^^^^^^^^
740
741Dynamically realigns the stack pointer to the specified size and alignment.
742An alignment value of `0` or `1` mean no specific alignment.
743
744.. code-block:: none
745
746  %8:_(p0) = G_DYN_STACKALLOC %7(s64), 32
747
748Optimization Hints
749------------------
750
751These instructions do not correspond to any target instructions. They act as
752hints for various combines.
753
754G_ASSERT_SEXT, G_ASSERT_ZEXT
755^^^^^^^^^^^^^^^^^^^^^^^^^^^^
756
757Signifies that the contents of a register were previously extended from a
758smaller type.
759
760The smaller type is denoted using an immediate operand. For scalars, this is the
761width of the entire smaller type. For vectors, this is the width of the smaller
762element type.
763
764.. code-block:: none
765
766  %x_was_zexted:_(s32) = G_ASSERT_ZEXT %x(s32), 16
767  %y_was_zexted:_(<2 x s32>) = G_ASSERT_ZEXT %y(<2 x s32>), 16
768
769  %z_was_sexted:_(s32) = G_ASSERT_SEXT %z(s32), 8
770
771G_ASSERT_SEXT and G_ASSERT_ZEXT act like copies, albeit with some restrictions.
772
773The source and destination registers must
774
775- Be virtual
776- Belong to the same register class
777- Belong to the same register bank
778
779It should always be safe to
780
781- Look through the source register
782- Replace the destination register with the source register
783