diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h --- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -499,6 +499,14 @@ TTI::OperandValueInfo Opd1Info, TTI::OperandValueInfo Opd2Info, ArrayRef 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(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 @@ 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 --- 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 @@ 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