1 /*
2 * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_OPTO_MULNODE_HPP
26 #define SHARE_OPTO_MULNODE_HPP
27
28 #include "opto/multnode.hpp"
29 #include "opto/node.hpp"
30 #include "opto/opcodes.hpp"
31 #include "opto/type.hpp"
32
33 // Portions of code courtesy of Clifford Click
34
35 class PhaseTransform;
36 class Matcher;
37
38 //------------------------------MulNode----------------------------------------
39 // Classic MULTIPLY functionality. This covers all the usual 'multiply'
40 // behaviors for an algebraic ring. Multiply-integer, multiply-float,
41 // multiply-double, and binary-and are all inherited from this class. The
42 // various identity values are supplied by virtual functions.
43 class MulNode : public Node {
44 virtual uint hash() const;
45 public:
46 MulNode(Node *in1, Node *in2): Node(nullptr,in1,in2) {
47 init_class_id(Class_Mul);
48 }
49
50 // Handle algebraic identities here. If we have an identity, return the Node
51 // we are equivalent to. We look for "add of zero" as an identity.
52 virtual Node* Identity(PhaseGVN* phase);
53
54 // We also canonicalize the Node, moving constants to the right input,
55 // and flatten expressions (so that 1+x+2 becomes x+3).
56 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
57
58 // Compute a new Type for this node. Basically we just do the pre-check,
59 // then call the virtual add() to set the type.
60 virtual const Type* Value(PhaseGVN* phase) const;
61
62 // Supplied function returns the product of the inputs.
63 // This also type-checks the inputs for sanity. Guaranteed never to
64 // be passed a TOP or BOTTOM type, these are filtered out by a pre-check.
65 // This call recognizes the multiplicative zero type.
66 virtual const Type *mul_ring( const Type *, const Type * ) const = 0;
67
68 // Supplied function to return the multiplicative identity type
69 virtual const Type *mul_id() const = 0;
70
71 // Supplied function to return the additive identity type
72 virtual const Type *add_id() const = 0;
73
74 // Supplied function to return the additive opcode
75 virtual int add_opcode() const = 0;
76
77 // Supplied function to return the multiplicative opcode
78 virtual int mul_opcode() const = 0;
79
80 // Supplied function to return the additive opcode
81 virtual int max_opcode() const = 0;
82
83 // Supplied function to return the multiplicative opcode
84 virtual int min_opcode() const = 0;
85
86 static MulNode* make(Node* in1, Node* in2, BasicType bt);
87 static MulNode* make_and(Node* in1, Node* in2, BasicType bt);
88
89 protected:
90 Node* AndIL_sum_and_mask(PhaseGVN* phase, BasicType bt);
91 };
92
93 //------------------------------MulINode---------------------------------------
94 // Multiply 2 integers
95 class MulINode : public MulNode {
96 public:
97 MulINode( Node *in1, Node *in2 ) : MulNode(in1,in2) {}
98 virtual int Opcode() const;
99 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
100 virtual const Type *mul_ring( const Type *, const Type * ) const;
101 static bool does_overflow(const TypeInt* type_left, const TypeInt* type_right);
102 const Type *mul_id() const { return TypeInt::ONE; }
103 const Type *add_id() const { return TypeInt::ZERO; }
104 int add_opcode() const { return Op_AddI; }
105 int mul_opcode() const { return Op_MulI; }
106 int max_opcode() const { return Op_MaxI; }
107 int min_opcode() const { return Op_MinI; }
108 const Type *bottom_type() const { return TypeInt::INT; }
109 virtual uint ideal_reg() const { return Op_RegI; }
110 };
111
112 //------------------------------MulLNode---------------------------------------
113 // Multiply 2 longs
114 class MulLNode : public MulNode {
115 public:
116 MulLNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {}
117 virtual int Opcode() const;
118 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
119 virtual const Type *mul_ring( const Type *, const Type * ) const;
120 const Type *mul_id() const { return TypeLong::ONE; }
121 const Type *add_id() const { return TypeLong::ZERO; }
122 int add_opcode() const { return Op_AddL; }
123 int mul_opcode() const { return Op_MulL; }
124 int max_opcode() const { return Op_MaxL; }
125 int min_opcode() const { return Op_MinL; }
126 const Type *bottom_type() const { return TypeLong::LONG; }
127 virtual uint ideal_reg() const { return Op_RegL; }
128 };
129
130
131 //------------------------------MulFNode---------------------------------------
132 // Multiply 2 floats
133 class MulFNode : public MulNode {
134 public:
135 MulFNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {}
136 virtual int Opcode() const;
137 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
138 virtual const Type *mul_ring( const Type *, const Type * ) const;
139 const Type *mul_id() const { return TypeF::ONE; }
140 const Type *add_id() const { return TypeF::ZERO; }
141 int add_opcode() const { return Op_AddF; }
142 int mul_opcode() const { return Op_MulF; }
143 int max_opcode() const { return Op_MaxF; }
144 int min_opcode() const { return Op_MinF; }
145 const Type *bottom_type() const { return Type::FLOAT; }
146 virtual uint ideal_reg() const { return Op_RegF; }
147 };
148
149 //------------------------------MulHFNode---------------------------------------
150 // Multiply 2 half floats
151 class MulHFNode : public MulNode {
152 public:
153 MulHFNode(Node* in1, Node* in2) : MulNode(in1, in2) {}
154 virtual int Opcode() const;
155 virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
156 virtual const Type* mul_ring(const Type*, const Type*) const;
157 const Type* mul_id() const { return TypeH::ONE; }
158 const Type* add_id() const { return TypeH::ZERO; }
159 int add_opcode() const { return Op_AddHF; }
160 int mul_opcode() const { return Op_MulHF; }
161 int max_opcode() const { return Op_MaxHF; }
162 int min_opcode() const { return Op_MinHF; }
163 const Type* bottom_type() const { return Type::HALF_FLOAT; }
164 virtual uint ideal_reg() const { return Op_RegF; }
165 };
166
167 //------------------------------MulDNode---------------------------------------
168 // Multiply 2 doubles
169 class MulDNode : public MulNode {
170 public:
171 MulDNode( Node *in1, Node *in2 ) : MulNode(in1,in2) {}
172 virtual int Opcode() const;
173 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
174 virtual const Type *mul_ring( const Type *, const Type * ) const;
175 const Type *mul_id() const { return TypeD::ONE; }
176 const Type *add_id() const { return TypeD::ZERO; }
177 int add_opcode() const { return Op_AddD; }
178 int mul_opcode() const { return Op_MulD; }
179 int max_opcode() const { return Op_MaxD; }
180 int min_opcode() const { return Op_MinD; }
181 const Type *bottom_type() const { return Type::DOUBLE; }
182 virtual uint ideal_reg() const { return Op_RegD; }
183 };
184
185 //-------------------------------MulHiLNode------------------------------------
186 const Type* MulHiValue(const Type *t1, const Type *t2, const Type *bot);
187
188 // Upper 64 bits of a 64 bit by 64 bit multiply
189 class MulHiLNode : public Node {
190 public:
191 MulHiLNode( Node *in1, Node *in2 ) : Node(nullptr,in1,in2) {}
192 virtual int Opcode() const;
193 virtual const Type* Value(PhaseGVN* phase) const;
194 const Type *bottom_type() const { return TypeLong::LONG; }
195 virtual uint ideal_reg() const { return Op_RegL; }
196 friend const Type* MulHiValue(const Type *t1, const Type *t2, const Type *bot);
197 };
198
199 // Upper 64 bits of a 64 bit by 64 bit unsigned multiply
200 class UMulHiLNode : public Node {
201 public:
202 UMulHiLNode( Node *in1, Node *in2 ) : Node(nullptr,in1,in2) {}
203 virtual int Opcode() const;
204 virtual const Type* Value(PhaseGVN* phase) const;
205 const Type *bottom_type() const { return TypeLong::LONG; }
206 virtual uint ideal_reg() const { return Op_RegL; }
207 friend const Type* MulHiValue(const Type *t1, const Type *t2, const Type *bot);
208 };
209
210 //------------------------------MulHiLoLNode-----------------------------------
211 // Lower and upper 64-bit results of a signed 64x64->128 multiply.
212 class MulHiLoLNode : public BinaryMultiNode {
213 protected:
214 MulHiLoLNode(Node* ctrl, Node* in1, Node* in2) : BinaryMultiNode(ctrl, in1, in2) {}
215
216 public:
217 virtual int Opcode() const;
218 virtual const Type* bottom_type() const { return TypeTuple::LONG_PAIR; }
219
220 virtual Node* match(const ProjNode* proj, const Matcher* m, const RegMask* mask);
221
222 static MulHiLoLNode* make(Node* mul_hi);
223 };
224
225 //------------------------------UMulHiLoLNode----------------------------------
226 // Lower and upper 64-bit results of an unsigned 64x64->128 multiply.
227 class UMulHiLoLNode : public MulHiLoLNode {
228 public:
229 UMulHiLoLNode(Node* ctrl, Node* in1, Node* in2) : MulHiLoLNode(ctrl, in1, in2) {}
230 virtual int Opcode() const;
231
232 static UMulHiLoLNode* make(Node* umul_hi);
233 };
234
235 //------------------------------AndINode---------------------------------------
236 // Logically AND 2 integers. Included with the MUL nodes because it inherits
237 // all the behavior of multiplication on a ring.
238 class AndINode : public MulINode {
239 public:
240 AndINode( Node *in1, Node *in2 ) : MulINode(in1,in2) {}
241 virtual int Opcode() const;
242 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
243 virtual Node* Identity(PhaseGVN* phase);
244 virtual const Type* Value(PhaseGVN* phase) const;
245 virtual const Type *mul_ring( const Type *, const Type * ) const;
246 const Type *mul_id() const { return TypeInt::MINUS_1; }
247 const Type *add_id() const { return TypeInt::ZERO; }
248 int add_opcode() const { return Op_OrI; }
249 int mul_opcode() const { return Op_AndI; }
250 int max_opcode() const { return Op_MaxI; }
251 int min_opcode() const { return Op_MinI; }
252 virtual uint ideal_reg() const { return Op_RegI; }
253 };
254
255 //------------------------------AndINode---------------------------------------
256 // Logically AND 2 longs. Included with the MUL nodes because it inherits
257 // all the behavior of multiplication on a ring.
258 class AndLNode : public MulLNode {
259 public:
260 AndLNode( Node *in1, Node *in2 ) : MulLNode(in1,in2) {}
261 virtual int Opcode() const;
262 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
263 virtual Node* Identity(PhaseGVN* phase);
264 virtual const Type* Value(PhaseGVN* phase) const;
265 virtual const Type *mul_ring( const Type *, const Type * ) const;
266 const Type *mul_id() const { return TypeLong::MINUS_1; }
267 const Type *add_id() const { return TypeLong::ZERO; }
268 int add_opcode() const { return Op_OrL; }
269 int mul_opcode() const { return Op_AndL; }
270 int max_opcode() const { return Op_MaxL; }
271 int min_opcode() const { return Op_MinL; }
272 virtual uint ideal_reg() const { return Op_RegL; }
273 };
274
275 template <typename TypeClass>
276 Node* make_and(Node* a, Node* b);
277
278 template <>
279 inline Node* make_and<TypeLong>(Node* a, Node* b) {
280 return new AndLNode(a, b);
281 }
282
283 template <>
284 inline Node* make_and<TypeInt>(Node* a, Node* b) {
285 return new AndINode(a, b);
286 }
287
288 class LShiftNode : public Node {
289 public:
290 LShiftNode(Node* in1, Node* in2) : Node(nullptr,in1,in2) {
291 init_class_id(Class_LShift);
292 }
293
294 const Type* ValueIL(PhaseGVN* phase, BasicType bt) const;
295 Node* IdentityIL(PhaseGVN* phase, BasicType bt);
296 Node* IdealIL(PhaseGVN* phase, bool can_reshape, BasicType bt);
297
298 static LShiftNode* make(Node* in1, Node* in2, BasicType bt);
299 };
300
301 //------------------------------LShiftINode------------------------------------
302 // Logical shift left
303 class LShiftINode : public LShiftNode {
304 public:
305 LShiftINode(Node* in1, Node* in2) : LShiftNode(in1,in2) {}
306 virtual int Opcode() const;
307 virtual Node* Identity(PhaseGVN* phase);
308 virtual Node* Ideal(PhaseGVN *phase, bool can_reshape);
309 virtual const Type* Value(PhaseGVN* phase) const;
310 const Type* bottom_type() const { return TypeInt::INT; }
311 virtual uint ideal_reg() const { return Op_RegI; }
312 };
313
314 //------------------------------LShiftLNode------------------------------------
315 // Logical shift left
316 class LShiftLNode : public LShiftNode {
317 public:
318 LShiftLNode(Node *in1, Node *in2) : LShiftNode(in1,in2) {}
319 virtual int Opcode() const;
320 virtual Node* Identity(PhaseGVN* phase);
321 virtual Node* Ideal(PhaseGVN *phase, bool can_reshape);
322 virtual const Type* Value(PhaseGVN* phase) const;
323 const Type* bottom_type() const { return TypeLong::LONG; }
324 virtual uint ideal_reg() const { return Op_RegL; }
325 };
326
327
328 //------------------------ RotateLeftNode ----------------------------------
329 class RotateLeftNode : public TypeNode {
330 public:
331 RotateLeftNode(Node* in1, Node* in2, const Type* type) : TypeNode(type, 3) {
332 init_req(1, in1);
333 init_req(2, in2);
334 }
335 virtual int Opcode() const;
336 virtual Node* Identity(PhaseGVN* phase);
337 virtual const Type* Value(PhaseGVN* phase) const;
338 virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
339 };
340
341 //----------------------- RotateRightNode ----------------------------------
342 class RotateRightNode : public TypeNode {
343 public:
344 RotateRightNode(Node* in1, Node* in2, const Type* type) : TypeNode(type, 3) {
345 init_req(1, in1);
346 init_req(2, in2);
347 }
348 virtual int Opcode() const;
349 virtual Node* Identity(PhaseGVN* phase);
350 virtual const Type* Value(PhaseGVN* phase) const;
351 };
352
353
354 class RShiftNode : public Node {
355 public:
356 RShiftNode(Node* in1, Node* in2) : Node(nullptr, in1, in2) {}
357 Node* IdealIL(PhaseGVN* phase, bool can_reshape, BasicType bt);
358 Node* IdentityIL(PhaseGVN* phase, BasicType bt);
359 const Type* ValueIL(PhaseGVN* phase, BasicType bt) const;
360 static RShiftNode* make(Node* in1, Node* in2, BasicType bt);
361 };
362
363 //------------------------------RShiftINode------------------------------------
364 // Signed shift right
365 class RShiftINode : public RShiftNode {
366 public:
367 RShiftINode(Node* in1, Node* in2) : RShiftNode(in1, in2) {}
368 virtual int Opcode() const;
369 virtual Node* Identity(PhaseGVN* phase);
370
371 virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
372 virtual const Type* Value(PhaseGVN* phase) const;
373
374 const Type* bottom_type() const { return TypeInt::INT; }
375 virtual uint ideal_reg() const { return Op_RegI; }
376 };
377
378 //------------------------------RShiftLNode------------------------------------
379 // Signed shift right
380 class RShiftLNode : public RShiftNode {
381 public:
382 RShiftLNode(Node* in1, Node* in2) : RShiftNode(in1,in2) {}
383 virtual int Opcode() const;
384 virtual Node* Identity(PhaseGVN* phase);
385 virtual Node* Ideal(PhaseGVN *phase, bool can_reshape);
386
387 virtual const Type* Value(PhaseGVN* phase) const;
388 const Type* bottom_type() const { return TypeLong::LONG; }
389 virtual uint ideal_reg() const { return Op_RegL; }
390 };
391
392 class URShiftNode : public Node {
393 public:
394 URShiftNode(Node* in1, Node* in2) : Node(nullptr, in1, in2) {}
395 static URShiftNode* make(Node* in1, Node* in2, BasicType bt);
396 };
397
398 //------------------------------URShiftBNode-----------------------------------
399 // Logical shift right
400 class URShiftBNode : public URShiftNode {
401 public:
402 URShiftBNode(Node* in1, Node* in2) : URShiftNode(in1,in2) {
403 ShouldNotReachHere(); // only vector variant is used
404 }
405 virtual int Opcode() const;
406 };
407
408 //------------------------------URShiftSNode-----------------------------------
409 // Logical shift right
410 class URShiftSNode : public URShiftNode {
411 public:
412 URShiftSNode(Node* in1, Node* in2) : URShiftNode(in1,in2) {
413 ShouldNotReachHere(); // only vector variant is used
414 }
415 virtual int Opcode() const;
416 };
417
418 //------------------------------URShiftINode-----------------------------------
419 // Logical shift right
420 class URShiftINode : public URShiftNode {
421 public:
422 URShiftINode(Node* in1, Node* in2) : URShiftNode(in1,in2) {}
423 virtual int Opcode() const;
424 virtual Node* Identity(PhaseGVN* phase);
425 virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
426 virtual const Type* Value(PhaseGVN* phase) const;
427 const Type* bottom_type() const { return TypeInt::INT; }
428 virtual uint ideal_reg() const { return Op_RegI; }
429 };
430
431 //------------------------------URShiftLNode-----------------------------------
432 // Logical shift right
433 class URShiftLNode : public URShiftNode {
434 public:
435 URShiftLNode(Node* in1, Node* in2) : URShiftNode(in1,in2) {}
436 virtual int Opcode() const;
437 virtual Node* Identity(PhaseGVN* phase);
438 virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
439 virtual const Type* Value(PhaseGVN* phase) const;
440 const Type* bottom_type() const { return TypeLong::LONG; }
441 virtual uint ideal_reg() const { return Op_RegL; }
442 };
443
444 template <typename TypeClass>
445 Node* make_urshift(Node* a, Node* b);
446
447 template <>
448 inline Node* make_urshift<TypeLong>(Node* a, Node* b) {
449 return new URShiftLNode(a, b);
450 }
451
452 template <>
453 inline Node* make_urshift<TypeInt>(Node* a, Node* b) {
454 return new URShiftINode(a, b);
455 }
456
457 //------------------------------FmaNode--------------------------------------
458 // fused-multiply-add
459 class FmaNode : public Node {
460 public:
461 FmaNode(Node* in1, Node* in2, Node* in3) : Node(nullptr, in1, in2, in3) {
462 assert(UseFMA, "Needs FMA instructions support.");
463 }
464 virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
465 };
466
467 //------------------------------FmaDNode--------------------------------------
468 // fused-multiply-add double
469 class FmaDNode : public FmaNode {
470 public:
471 FmaDNode(Node* in1, Node* in2, Node* in3) : FmaNode(in1, in2, in3) {}
472 virtual int Opcode() const;
473 const Type* bottom_type() const { return Type::DOUBLE; }
474 virtual uint ideal_reg() const { return Op_RegD; }
475 virtual const Type* Value(PhaseGVN* phase) const;
476 };
477
478 //------------------------------FmaFNode--------------------------------------
479 // fused-multiply-add float
480 class FmaFNode : public FmaNode {
481 public:
482 FmaFNode(Node* in1, Node* in2, Node* in3) : FmaNode(in1, in2, in3) {}
483 virtual int Opcode() const;
484 const Type* bottom_type() const { return Type::FLOAT; }
485 virtual uint ideal_reg() const { return Op_RegF; }
486 virtual const Type* Value(PhaseGVN* phase) const;
487 };
488
489 //------------------------------FmaHFNode-------------------------------------
490 // fused-multiply-add half-precision float
491 class FmaHFNode : public FmaNode {
492 public:
493 FmaHFNode(Node* in1, Node* in2, Node* in3) : FmaNode(in1, in2, in3) {}
494 virtual int Opcode() const;
495 const Type* bottom_type() const { return Type::HALF_FLOAT; }
496 virtual uint ideal_reg() const { return Op_RegF; }
497 virtual const Type* Value(PhaseGVN* phase) const;
498 };
499
500 //------------------------------MulAddS2INode----------------------------------
501 // Multiply shorts into integers and add them.
502 // Semantics: I_OUT = S1 * S2 + S3 * S4
503 class MulAddS2INode : public Node {
504 virtual uint hash() const;
505 public:
506 MulAddS2INode(Node* in1, Node *in2, Node *in3, Node* in4) : Node(nullptr, in1, in2, in3, in4) {}
507 virtual int Opcode() const;
508 const Type *bottom_type() const { return TypeInt::INT; }
509 virtual uint ideal_reg() const { return Op_RegI; }
510 };
511
512 #endif // SHARE_OPTO_MULNODE_HPP