llvm-project/llvm/test/Transforms/LICM
Max Kazantsev b9e65cbddf Introduce llvm.experimental.widenable_condition intrinsic
This patch introduces a new instinsic `@llvm.experimental.widenable_condition`
that allows explicit representation for guards. It is an alternative to using
`@llvm.experimental.guard` intrinsic that does not contain implicit control flow.

We keep finding places where `@llvm.experimental.guard` is not supported or
treated too conservatively, and there are 2 reasons to that:

- `@llvm.experimental.guard` has memory write side effect to model implicit control flow,
  and this sometimes confuses passes and analyzes that work with memory;
- Not all passes and analysis are aware of the semantics of guards. These passes treat them
  as regular throwing call and have no idea that the condition of guard may be used to prove
  something. One well-known place which had caused us troubles in the past is explicit loop
  iteration count calculation in SCEV. Another example is new loop unswitching which is not
  aware of guards. Whenever a new pass appears, we potentially have this problem there.

Rather than go and fix all these places (and commit to keep track of them and add support
in future), it seems more reasonable to leverage the existing optimizer's logic as much as possible.
The only significant difference between guards and regular explicit branches is that guard's condition
can be widened. It means that a guard contains (explicitly or implicitly) a `deopt` block successor,
and it is always legal to go there no matter what the guard condition is. The other successor is
a guarded block, and it is only legal to go there if the condition is true.

This patch introduces a new explicit form of guards alternative to `@llvm.experimental.guard`
intrinsic. Now a widenable guard can be represented in the CFG explicitly like this:


    %widenable_condition = call i1 @llvm.experimental.widenable.condition()
    %new_condition = and i1 %cond, %widenable_condition
    br i1 %new_condition, label %guarded, label %deopt

  guarded:
    ; Guarded instructions

  deopt:
    call type @llvm.experimental.deoptimize(<args...>) [ "deopt"(<deopt_args...>) ]

The new intrinsic `@llvm.experimental.widenable.condition` has semantics of an
`undef`, but the intrinsic prevents the optimizer from folding it early. This form
should exploit all optimization boons provided to `br` instuction, and it still can be
widened by replacing the result of `@llvm.experimental.widenable.condition()`
with `and` with any arbitrary boolean value (as long as the branch that is taken when
it is `false` has a deopt and has no side-effects).

For more motivation, please check llvm-dev discussion "[llvm-dev] Giving up using
implicit control flow in guards".

This patch introduces this new intrinsic with respective LangRef changes and a pass
that converts old-style guards (expressed as intrinsics) into the new form.

The naming discussion is still ungoing. Merging this to unblock further items. We can
later change the name of this intrinsic.

Reviewed By: reames, fedor.sergeev, sanjoy
Differential Revision: https://reviews.llvm.org/D51207

llvm-svn: 348593
2018-12-07 14:39:46 +00:00
..
2003-02-26-LoopExitNotDominated.ll
2003-02-27-NestedLoopExitBlocks.ll
2003-02-27-PreheaderExitNodeUpdate.ll
2003-02-27-PreheaderProblem.ll
2003-02-27-StoreSinkPHIs.ll
2003-02-28-PromoteDifferentType.ll
2003-05-02-LoadHoist.ll
2003-12-11-SinkingToPHI.ll
2004-09-14-AliasAnalysisInvalidate.ll
2004-11-17-UndefIndexCrash.ll
2006-09-12-DeadUserOfSunkInstr.ll
2007-05-22-VolatileSink.ll
2007-07-30-AliasSet.ll
2007-09-17-PromoteValue.ll
2007-09-24-PromoteNullValue.ll
2007-10-01-PromoteSafeValue.ll
2008-05-20-AliasSetVAArg.ll
2008-07-22-LoadGlobalConstant.ll
2009-12-10-LICM-Indbr-Crash.ll
2011-04-06-HoistMissedASTUpdate.ll
2011-04-06-PromoteResultOfPromotion.ll
2011-04-09-RAUW-AST.ll
2011-07-06-Alignment.ll
2014-09-10-doFinalizationAssert.ll
AliasSetMemSet.ll
PR19798.ll
PR21582.ll
PR24013.ll
Preserve-LCSSA.ll
alias-set-tracker-loss.ll
argmemonly-call.ll [AST] Generalize argument specific aliasing 2018-09-07 21:36:11 +00:00
assume.ll [LICM] Hoist assumes out of loops 2018-08-10 22:21:56 +00:00
atomics.ll [LICM] Hoist stores of invariant values to invariant addresses out of loops 2018-08-29 21:49:30 +00:00
basictest.ll
bisect-state.ll
call-hoisting.ll [LICM] Fix a test so it actualy checks what was meant [NFC] 2018-08-21 21:27:26 +00:00
constexpr.ll
crash.ll
debug-value.ll
dropped-tbaa.ll
explicit_guards.ll Introduce llvm.experimental.widenable_condition intrinsic 2018-12-07 14:39:46 +00:00
extra-copies.ll
fence.ll [LICM] hoist fences out of loops w/o memory operations 2018-08-09 20:18:42 +00:00
funclet.ll [LICM] Hoist stores of invariant values to invariant addresses out of loops 2018-08-29 21:49:30 +00:00
guards.ll [LICM] Hoist guards from non-header blocks 2018-11-12 09:29:58 +00:00
hoist-bitcast-load.ll
hoist-debuginvariant.ll [MustExecute] Fix a debug invariant issue in isGuaranteedToExecute() 2018-05-25 13:02:59 +00:00
hoist-deref-load.ll Re-enable "[ValueTracking] Teach isKnownNonNullFromDominatingCondition about AND" 2018-08-06 11:14:18 +00:00
hoist-fast-fdiv.ll Fix invariant fdiv hoisting in LICM 2018-06-23 04:01:28 +00:00
hoist-invariant-load.ll
hoist-mustexec.ll [LICM] Use ICFLoopSafetyInfo in LICM 2018-11-06 02:44:49 +00:00
hoist-nounwind.ll [LICM] Use ICFLoopSafetyInfo in LICM 2018-11-06 02:44:49 +00:00
hoist-phi.ll [LICM] Reapply r347776 "Make LICM able to hoist phis" with fix 2018-11-29 17:10:00 +00:00
hoist-round.ll [InstCombine] InstCombine and InstSimplify for minimum and maximum 2018-10-19 19:01:26 +00:00
hoisting.ll [LICM] Add tests from D50786 [NFC] 2018-08-21 00:42:07 +00:00
infinite_loops.ll [MustExecute] Fix algorithmic bug in isGuaranteedToExecute. PR38514 2018-08-17 06:19:17 +00:00
int_sideeffect.ll
invariant.start.ll [LICM] Hoist an invariant_start out of loops if there are no stores executed before it 2018-08-24 16:24:48 +00:00
lcssa-ssa-promoter.ll
loopsink-pr38462.ll LoopSink: Don't sink into blocks without an insertion point (PR38462) 2018-08-29 06:55:27 +00:00
loopsink-pr39570.ll [LoopSink] Do not sink instructions into non-cold blocks 2018-11-07 18:26:24 +00:00
loopsink-pr39695.ll [LoopSink] Add preheader to alias set 2018-11-20 16:49:07 +00:00
loopsink.ll NFC - Various typo fixes in tests 2018-07-04 13:28:39 +00:00
no-preheader-test.ll
opt-remarks-conditional-load.ll [DebugInfo] Add DILabel metadata and intrinsic llvm.dbg.label. 2018-05-09 02:40:45 +00:00
opt-remarks-intervening-store.ll [DebugInfo] Add DILabel metadata and intrinsic llvm.dbg.label. 2018-05-09 02:40:45 +00:00
opt-remarks.ll [DebugInfo] Add DILabel metadata and intrinsic llvm.dbg.label. 2018-05-09 02:40:45 +00:00
pr23608.ll
pr26843.ll
pr27262.ll
pr32129.ll
pr35342.ll
pr36228.ll [Analysis] Make LocationSizes carry an 'imprecise' bit 2018-10-10 06:39:40 +00:00
pr37323.ll [LICM] Preserve DT and LoopInfo specifically 2018-05-24 15:58:34 +00:00
preheader-safe.ll [LICM] Use ICFLoopSafetyInfo in LICM 2018-11-06 02:44:49 +00:00
promote-order.ll [LICM] Hoist stores of invariant values to invariant addresses out of loops 2018-08-29 21:49:30 +00:00
promote-tls.ll
read-only-calls.ll [LICM] Add a diagnostic analysis for identifying alias information 2018-08-17 13:44:00 +00:00
scalar-promote-memmodel.ll
scalar-promote-unwind.ll
scalar-promote.ll [LICM] Add tests from D50786 [NFC] 2018-08-21 00:42:07 +00:00
sink-foldable.ll
sink.ll
sinking.ll [LICM] Remove unneccessary safety check to increase sinking effectiveness 2018-08-03 00:21:56 +00:00
speculate.ll
store-hoisting.ll Add a todo and tests to Address a review commnt from D50925 [NFC] 2018-08-29 22:09:21 +00:00
strlen.ll
unrolled-deeply-nested.ll
update-scev.ll
volatile-alias.ll