@@ -404,11 +404,32 @@ The use of TargetTransformInfo is only allowed for hooks for target-specific
404
404
intrinsics, such as ` TargetTransformInfo::instCombineIntrinsic() ` . These are
405
405
already inherently target-dependent anyway.
406
406
407
+ If some canonicalization narrow/widen the integer width of expressions, please
408
+ check ` shouldChangeType() ` first. Otherwise, we may evaluate the expression
409
+ in illegal/inefficient types.
410
+
407
411
For vector-specific transforms that require cost-modelling, the VectorCombine
408
412
pass can be used instead. In very rare circumstances, if there are no other
409
413
alternatives, target-dependent transforms may be accepted into
410
414
AggressiveInstCombine.
411
415
416
+ Generally, we prefer unsigned operations over signed operations in the middle-end, even
417
+ if signed operations are more efficient on some targets. The following is an incomplete
418
+ list of canonicalizations that are implemented in InstCombine:
419
+
420
+ | Original Pattern | Canonical Form | Condition |
421
+ | ------------------------------| ----------------------------| -------------------------------|
422
+ | ` icmp spred X, Y ` | ` icmp samesign upred X, Y ` | ` sign(X) == sign(Y) ` |
423
+ | ` smin/smax X, Y ` | ` umin/umax X, Y ` | ` sign(X) == sign(Y) ` |
424
+ | ` sext X ` | ` zext nneg X ` | ` X >=s 0 ` |
425
+ | ` sitofp X ` | ` uitofp nneg X ` | ` X >=s 0 ` |
426
+ | ` ashr X, Y ` | ` lshr X, Y ` | ` X >=s 0 ` |
427
+ | ` sdiv/srem X, Y ` | ` udiv/urem X, Y ` | ` X >=s 0 && Y >=s 0 ` |
428
+ | ` add X, Y ` | ` or disjoint X, Y ` | ` (X & Y) != 0 ` |
429
+ | ` mul X, C ` | ` shl X, Log2(C) ` | ` isPowerOf2(C) ` |
430
+ | ` select Cond1, Cond2, false ` | ` and Cond1, Cond2 ` | ` impliesPoison(Cond2, Cond1) ` |
431
+ | ` select Cond1, true, Cond2 ` | ` or Cond1, Cond2 ` | ` impliesPoison(Cond2, Cond1) ` |
432
+
412
433
### PatternMatch
413
434
414
435
Many transforms make use of the matching infrastructure defined in
@@ -531,6 +552,19 @@ need to add a one-use check for the inner instruction.
531
552
One-use checks can be performed using the ` m_OneUse() ` matcher, or the
532
553
` V->hasOneUse() ` method.
533
554
555
+ ### Flag handling
556
+
557
+ When possible, favour propagation of poison-generating flags like ` nuw ` and ` nsw ` since they may be
558
+ hard to salvage later. Avoid doing so if it introduces additional complexity (e.g. requires querying ` willNotOverflow `
559
+ or KnownBits).
560
+
561
+ Be careful with in-place operand/predicate changes, as poison-generating flags may not be valid for new
562
+ operands. It is recommended to create a new instruction with careful handling of flags. If not
563
+ applicable, call ` Instruction::dropPoisonGeneratingFlags() ` to clear flags in a conservative manner.
564
+
565
+ Do not rely on fcmp's ` nsz ` flag to perform optimizations. It is meaningless for fcmp so it should not affect
566
+ the optimization.
567
+
534
568
### Generalization
535
569
536
570
Transforms can both be too specific (only handling some odd subset of patterns,
@@ -558,6 +592,11 @@ guidelines.
558
592
use of ValueTracking queries. Whether this makes sense depends on the case,
559
593
but it's usually a good idea to only handle the constant pattern first, and
560
594
then generalize later if it seems useful.
595
+ * When possible, handle more canonical patterns as well. It is encouraged to avoid
596
+ potential phase-ordering issues. For example, if the motivating transform holds for
597
+ ` add ` , it also holds for ` or disjoint ` . See the canonicalization list above for details.
598
+ In most cases, it can be easily implemented with matchers like
599
+ ` m_AddLike/m_SExtLike/m_LogicalAnd/m_LogicalOr ` .
561
600
562
601
## Guidelines for reviewers
563
602
0 commit comments