2 Copyright 1988-2022 Free Software Foundation, Inc.
3 This is part of the GCC manual.
4 For copying conditions, see the copyright.rst file.
6 .. index:: canonicalization of instructions, insn canonicalization
8 .. _insn-canonicalizations:
10 Canonicalization of Instructions
11 ********************************
13 There are often cases where multiple RTL expressions could represent an
14 operation performed by a single machine instruction. This situation is
15 most commonly encountered with logical, branch, and multiply-accumulate
16 instructions. In such cases, the compiler attempts to convert these
17 multiple RTL expressions into a single canonical form to reduce the
18 number of insn patterns required.
20 In addition to algebraic simplifications, following canonicalizations
23 * For commutative and comparison operators, a constant is always made the
24 second operand. If a machine only supports a constant as the second
25 operand, only patterns that match a constant in the second operand need
28 * For associative operators, a sequence of operators will always chain
29 to the left; for instance, only the left operand of an integer ``plus``
30 can itself be a ``plus``. ``and``, ``ior``, ``xor``,
31 ``plus``, ``mult``, ``smin``, ``smax``, ``umin``, and
32 ``umax`` are associative when applied to integers, and sometimes to
35 .. index:: neg, canonicalization of, not, canonicalization of, mult, canonicalization of, plus, canonicalization of, minus, canonicalization of
37 * For these operators, if only one operand is a ``neg``, ``not``,
38 ``mult``, ``plus``, or ``minus`` expression, it will be the
41 * In combinations of ``neg``, ``mult``, ``plus``, and
42 ``minus``, the ``neg`` operations (if any) will be moved inside
43 the operations as far as possible. For instance,
44 ``(neg (mult A B))`` is canonicalized as ``(mult (neg A) B)``, but
45 ``(plus (mult (neg B) C) A)`` is canonicalized as
46 ``(minus A (mult B C))``.
48 .. index:: compare, canonicalization of
50 * For the ``compare`` operator, a constant is always the second operand
51 if the first argument is a condition code register.
53 * For instructions that inherently set a condition code register, the
54 ``compare`` operator is always written as the first RTL expression of
55 the ``parallel`` instruction pattern. For example,
60 [(set (reg:CCZ FLAGS_REG)
63 (match_operand:SI 1 "register_operand" "%r")
64 (match_operand:SI 2 "register_operand" "r"))
66 (set (match_operand:SI 0 "register_operand" "=r")
67 (plus:SI (match_dup 1) (match_dup 2)))]
71 * An operand of ``neg``, ``not``, ``mult``, ``plus``, or
72 ``minus`` is made the first operand under the same conditions as
75 * ``(ltu (plus ab) b)`` is converted to
76 ``(ltu (plus ab) a)``. Likewise with ``geu`` instead
79 * ``(minus x (const_int n))`` is converted to
80 ``(plus x (const_int -n))``.
82 * Within address computations (i.e., inside ``mem``), a left shift is
83 converted into the appropriate multiplication by a power of two.
85 .. index:: ior, canonicalization of, and, canonicalization of, De Morgan's law
87 * De Morgan's Law is used to move bitwise negation inside a bitwise
88 logical-and or logical-or operation. If this results in only one
89 operand being a ``not`` expression, it will be the first one.
91 A machine that has an instruction that performs a bitwise logical-and of one
92 operand with the bitwise negation of the other should specify the pattern
93 for that instruction as
98 [(set (match_operand:m 0 ...)
99 (and:m (not:m (match_operand:m 1 ...))
100 (match_operand:m 2 ...)))]
104 Similarly, a pattern for a 'NAND' instruction should be written
109 [(set (match_operand:m 0 ...)
110 (ior:m (not:m (match_operand:m 1 ...))
111 (not:m (match_operand:m 2 ...))))]
115 In both cases, it is not necessary to include patterns for the many
116 logically equivalent RTL expressions.
118 .. index:: xor, canonicalization of
120 * The only possible RTL expressions involving both bitwise exclusive-or
121 and bitwise negation are ``(xor:mxy)``
122 and ``(not:m (xor:mxy))``.
124 * The sum of three items, one of which is a constant, will only appear in
129 (plus:m (plus:m x y) constant)
131 .. index:: zero_extract, canonicalization of, sign_extract, canonicalization of
133 * Equality comparisons of a group of bits (usually a single bit) with zero
134 will be written using ``zero_extract`` rather than the equivalent
135 ``and`` or ``sign_extract`` operations.
137 .. index:: mult, canonicalization of
139 * ``(sign_extend:m1 (mult:m2 (sign_extend:m2x)
140 (sign_extend:m2y)))`` is converted to ``(mult:m1
141 (sign_extend:m1x) (sign_extend:m1y))``, and likewise
144 * ``(sign_extend:m1 (mult:m2 (ashiftrt:m2xs) (sign_extend:m2y)))`` is converted
145 to ``(mult:m1 (sign_extend:m1 (ashiftrt:m2xs)) (sign_extend:m1y))``, and likewise for
146 patterns using ``zero_extend`` and ``lshiftrt``. If the second
147 operand of ``mult`` is also a shift, then that is extended also.
148 This transformation is only applied when it can be proven that the
149 original operation had sufficient precision to prevent overflow.
151 Further canonicalization rules are defined in the function
152 ``commutative_operand_precedence`` in :samp:`gcc/rtlanal.cc`.