36
38
# For optimizing extract->convert sequences for unpack/pack norm
37
39
(('u2f32', ('u2u32', a)), ('u2f32', a)),
38
40
(('i2f32', ('i2i32', a)), ('i2f32', a)),
42
# These are based on the lowerings from nir_opt_algebraic, but conditioned
43
# on the number of bits not being constant. If the bit count is constant
44
# (the happy path) we can use our native instruction instead.
45
(('ibitfield_extract', 'value', 'offset', 'bits(is_not_const)'),
46
('bcsel', ('ieq', 0, 'bits'),
49
('ishl', 'value', ('isub', ('isub', 32, 'bits'), 'offset')),
50
('isub', 32, 'bits')))),
52
(('ubitfield_extract', 'value', 'offset', 'bits(is_not_const)'),
54
('ushr', 'value', 'offset'),
55
('bcsel', ('ieq', 'bits', 32),
57
('isub', ('ishl', 1, 'bits'), 1)))),
59
# Codegen depends on this trivial case being optimized out.
60
(('ubitfield_extract', 'value', 'offset', 0), 0),
61
(('ibitfield_extract', 'value', 'offset', 0), 0),
63
# At this point, bitfield extracts are constant. We can only do constant
64
# unsigned bitfield extract, so lower signed to unsigned + sign extend.
65
(('ibitfield_extract', a, b, '#bits'),
66
('ishr', ('ishl', ('ubitfield_extract', a, b, 'bits'), ('isub', 32, 'bits')),
67
('isub', 32, 'bits'))),
70
# (x * y) + s = (x * y) + (s << 0)
72
return ('imadshl_agx', x, y, z, 0)
74
# (x * y) - s = (x * y) - (s << 0)
76
return ('imsubshl_agx', x, y, z, 0)
78
# x + (y << s) = (x * 1) + (y << s)
80
return ('imadshl_agx', x, 1, y, s)
82
# x - (y << s) = (x * 1) - (y << s)
84
return ('imsubshl_agx', x, 1, y, s)
87
# Reassociate imul+iadd chain in order to fuse imads. This pattern comes up
88
# in compute shader lowering.
89
(('iadd', ('iadd(is_used_once)', ('imul(is_used_once)', a, b),
90
('imul(is_used_once)', c, d)), e),
91
imad(a, b, imad(c, d, e))),
94
(('iadd', ('imul(is_used_once)', a, b), c), imad(a, b, c)),
95
(('isub', ('imul(is_used_once)', a, b), c), imsub(a, b, c)),
101
(('iadd', a, ('ishl(is_used_once)', b, s)), iaddshl(a, b, s)),
102
(('isub', a, ('ishl(is_used_once)', b, s)), isubshl(a, b, s)),
105
(('ineg', ('ishl(is_used_once)', b, s)), isubshl(0, b, s)),
108
(imad(a, b, ('ishl(is_used_once)', c, s)), ('imadshl_agx', a, b, c, s)),
109
(imsub(a, b, ('ishl(is_used_once)', c, s)), ('imsubshl_agx', a, b, c, s)),
111
# a + (a << s) = a + a * (1 << s) = a * (1 + (1 << s))
112
(('imul', a, 1 + (1 << s)), iaddshl(a, a, s)),
114
# a - (a << s) = a - a * (1 << s) = a * (1 - (1 << s))
115
(('imul', a, 1 - (1 << s)), isubshl(a, a, s)),
117
# a - (a << s) = a * (1 - (1 << s)) = -(a * (1 << s) - 1)
118
(('ineg', ('imul(is_used_once)', a, (1 << s) - 1)), isubshl(a, a, s)),
120
# iadd is SCIB, general shfit is IC (slower)
121
(('ishl', a, s), iaddshl(0, a, s)),
124
# Discard lowering generates this pattern, clean it up
126
(('ixor', ('bcsel', a, '#b', '#c'), '#d'),
127
('bcsel', a, ('ixor', b, d), ('ixor', c, d))),