[llvm] d12af65 - [TTI] Treat AND/OR with widenable conditions as free of cost

Max Kazantsev via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 14 06:55:25 PDT 2023


Author: Max Kazantsev
Date: 2023-03-14T20:55:17+07:00
New Revision: d12af65d4626ac69faf8f56afd30971b8a2fc3b3

URL: https://github.com/llvm/llvm-project/commit/d12af65d4626ac69faf8f56afd30971b8a2fc3b3
DIFF: https://github.com/llvm/llvm-project/commit/d12af65d4626ac69faf8f56afd30971b8a2fc3b3.diff

LOG: [TTI] Treat AND/OR with widenable conditions as free of cost

Because widenable conditions with eventually lower into a constant, such instructions
as `and`, `or` etc. will also be optimized away. Treat them as free.

This is an important thing to have if we want that guards represented as experimental.guard
calls and in their explicit form (branch by `and` with widenable condition) have the same cost
for unroller and other passes like this.

Differential Revision: https://reviews.llvm.org/D146034
Reviewed By: nikic

Added: 
    

Modified: 
    llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
    llvm/test/Transforms/LoopUnroll/guard-cost-for-unrolling.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
index 7ebfa054818b..e18c5b158715 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -499,6 +499,14 @@ class TargetTransformInfoImplBase {
       TTI::OperandValueInfo Opd1Info, TTI::OperandValueInfo Opd2Info,
       ArrayRef<const Value *> Args,
       const Instruction *CxtI = nullptr) const {
+    // Widenable conditions will eventually lower into constants, so some
+    // operations with them will be trivially optimized away.
+    auto IsWidenableCondition = [](const Value *V) {
+      if (auto *II = dyn_cast<IntrinsicInst>(V))
+        if (II->getIntrinsicID() == Intrinsic::experimental_widenable_condition)
+          return true;
+      return false;
+    };
     // FIXME: A number of transformation tests seem to require these values
     // which seems a little odd for how arbitary there are.
     switch (Opcode) {
@@ -512,6 +520,11 @@ class TargetTransformInfoImplBase {
     case Instruction::URem:
       // FIXME: Unlikely to be true for CodeSize.
       return TTI::TCC_Expensive;
+    case Instruction::And:
+    case Instruction::Or:
+      if (any_of(Args, IsWidenableCondition))
+        return TTI::TCC_Free;
+      break;
     }
 
     // Assume a 3cy latency for fp arithmetic ops.

diff  --git a/llvm/test/Transforms/LoopUnroll/guard-cost-for-unrolling.ll b/llvm/test/Transforms/LoopUnroll/guard-cost-for-unrolling.ll
index 37f5e3a8649d..596c12dae077 100644
--- a/llvm/test/Transforms/LoopUnroll/guard-cost-for-unrolling.ll
+++ b/llvm/test/Transforms/LoopUnroll/guard-cost-for-unrolling.ll
@@ -2,7 +2,7 @@
 
 ; REQUIRES: asserts
 
-; FIXME: This test is needed to make sure that the guard cost remains the same,
+; This test is needed to make sure that the guard cost remains the same,
 ; independently on guard representation form (either intrinsic call or branch with
 ; widenable condition).
 
@@ -30,7 +30,7 @@ exit:
 
 define void @test_guard_as_branch(ptr %arr, i64 %n, i64 %bound) {
 ; CHECK-LABEL: Loop Unroll: F[test_guard_as_branch] Loop %loop
-; CHECK-NEXT:    Loop Size = 9
+; CHECK-NEXT:    Loop Size = 8
 ; CHECK-NEXT:    runtime unrolling with count: 2
 entry:
   br label %loop


        


More information about the llvm-commits mailing list