Changeset View
Changeset View
Standalone View
Standalone View
llvm/test/Transforms/MakeGuardsExplicit/basic.ll
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | ||||
; RUN: opt -S -make-guards-explicit < %s | FileCheck %s | ; RUN: opt -S -make-guards-explicit < %s | FileCheck %s | ||||
; RUN: opt -S -passes=make-guards-explicit < %s | FileCheck %s | ; RUN: opt -S -passes=make-guards-explicit < %s | FileCheck %s | ||||
declare void @llvm.experimental.guard(i1,...) | declare void @llvm.experimental.guard(i1,...) | ||||
; Check that a sole guard can be turned into explicit guards form. | ; Check that a sole guard can be turned into explicit guards form. | ||||
define void @trivial_guard(i1 %cond) { | define void @trivial_guard(i1 %cond) { | ||||
; CHECK-LABEL: @trivial_guard( | ; CHECK-LABEL: @trivial_guard( | ||||
; CHECK-NEXT: entry: | ; CHECK-NEXT: entry: | ||||
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() | ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() | ||||
; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND:%.*]], [[WIDENABLE_COND]] | ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND:%.*]], [[WIDENABLE_COND]] | ||||
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0 | ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !make.implicit !0 | ||||
; CHECK: deopt: | ; CHECK: deopt: | ||||
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 123, i64 456) ] | ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 123, i64 456) ] | ||||
; CHECK-NEXT: ret void | ; CHECK-NEXT: ret void | ||||
; CHECK: guarded: | ; CHECK: guarded: | ||||
; CHECK-NEXT: ret void | ; CHECK-NEXT: ret void | ||||
; | ; | ||||
entry: | entry: | ||||
call void(i1, ...) @llvm.experimental.guard(i1 %cond) [ "deopt"(i32 123, i64 456) ] | call void(i1, ...) @llvm.experimental.guard(i1 %cond) [ "deopt"(i32 123, i64 456) ] | ||||
ret void | ret void | ||||
} | } | ||||
; Check that a sequence of guards can be turned into explicit guards form. | ; Check that a sequence of guards can be turned into explicit guards form. | ||||
define void @trivial_guard_sequence(i1 %cond1, i1 %cond2, i1 %cond3) { | define void @trivial_guard_sequence(i1 %cond1, i1 %cond2, i1 %cond3) { | ||||
; CHECK-LABEL: @trivial_guard_sequence( | ; CHECK-LABEL: @trivial_guard_sequence( | ||||
; CHECK-NEXT: entry: | ; CHECK-NEXT: entry: | ||||
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() | ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() | ||||
; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND1:%.*]], [[WIDENABLE_COND]] | ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND1:%.*]], [[WIDENABLE_COND]] | ||||
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0 | ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !make.implicit !0 | ||||
; CHECK: deopt: | ; CHECK: deopt: | ||||
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 123, i64 456) ] | ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 123, i64 456) ] | ||||
; CHECK-NEXT: ret void | ; CHECK-NEXT: ret void | ||||
; CHECK: guarded: | ; CHECK: guarded: | ||||
; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition() | ; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition() | ||||
; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND2:%.*]], [[WIDENABLE_COND3]] | ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND2:%.*]], [[WIDENABLE_COND3]] | ||||
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0 | ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !make.implicit !0 | ||||
; CHECK: deopt2: | ; CHECK: deopt2: | ||||
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 789, i64 123) ] | ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 789, i64 123) ] | ||||
; CHECK-NEXT: ret void | ; CHECK-NEXT: ret void | ||||
; CHECK: guarded1: | ; CHECK: guarded1: | ||||
; CHECK-NEXT: [[WIDENABLE_COND7:%.*]] = call i1 @llvm.experimental.widenable.condition() | ; CHECK-NEXT: [[WIDENABLE_COND7:%.*]] = call i1 @llvm.experimental.widenable.condition() | ||||
; CHECK-NEXT: [[EXIPLICIT_GUARD_COND8:%.*]] = and i1 [[COND3:%.*]], [[WIDENABLE_COND7]] | ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND8:%.*]] = and i1 [[COND3:%.*]], [[WIDENABLE_COND7]] | ||||
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND8]], label [[GUARDED5:%.*]], label [[DEOPT6:%.*]], !prof !0 | ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND8]], label [[GUARDED5:%.*]], label [[DEOPT6:%.*]], !make.implicit !0 | ||||
; CHECK: deopt6: | ; CHECK: deopt6: | ||||
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 456, i64 789) ] | ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 456, i64 789) ] | ||||
; CHECK-NEXT: ret void | ; CHECK-NEXT: ret void | ||||
; CHECK: guarded5: | ; CHECK: guarded5: | ||||
; CHECK-NEXT: ret void | ; CHECK-NEXT: ret void | ||||
; | ; | ||||
entry: | entry: | ||||
call void(i1, ...) @llvm.experimental.guard(i1 %cond1) [ "deopt"(i32 123, i64 456) ] | call void(i1, ...) @llvm.experimental.guard(i1 %cond1) [ "deopt"(i32 123, i64 456) ] | ||||
call void(i1, ...) @llvm.experimental.guard(i1 %cond2) [ "deopt"(i32 789, i64 123) ] | call void(i1, ...) @llvm.experimental.guard(i1 %cond2) [ "deopt"(i32 789, i64 123) ] | ||||
call void(i1, ...) @llvm.experimental.guard(i1 %cond3) [ "deopt"(i32 456, i64 789) ] | call void(i1, ...) @llvm.experimental.guard(i1 %cond3) [ "deopt"(i32 456, i64 789) ] | ||||
ret void | ret void | ||||
} | } | ||||
; Check that all instructions between the guards preserve. | ; Check that all instructions between the guards preserve. | ||||
define void @split_block_contents(i1 %cond1, i1 %cond2, i1 %cond3, i32* %p) { | define void @split_block_contents(i1 %cond1, i1 %cond2, i1 %cond3, i32* %p) { | ||||
; CHECK-LABEL: @split_block_contents( | ; CHECK-LABEL: @split_block_contents( | ||||
; CHECK-NEXT: entry: | ; CHECK-NEXT: entry: | ||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]] | ; CHECK-NEXT: store i32 0, i32* [[P:%.*]] | ||||
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() | ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() | ||||
; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND1:%.*]], [[WIDENABLE_COND]] | ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND1:%.*]], [[WIDENABLE_COND]] | ||||
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0 | ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !make.implicit !0 | ||||
; CHECK: deopt: | ; CHECK: deopt: | ||||
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 123, i64 456) ] | ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 123, i64 456) ] | ||||
; CHECK-NEXT: ret void | ; CHECK-NEXT: ret void | ||||
; CHECK: guarded: | ; CHECK: guarded: | ||||
; CHECK-NEXT: store i32 1, i32* [[P]] | ; CHECK-NEXT: store i32 1, i32* [[P]] | ||||
; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition() | ; CHECK-NEXT: [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition() | ||||
; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND2:%.*]], [[WIDENABLE_COND3]] | ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[COND2:%.*]], [[WIDENABLE_COND3]] | ||||
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0 | ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND4]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !make.implicit !0 | ||||
; CHECK: deopt2: | ; CHECK: deopt2: | ||||
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 789, i64 123) ] | ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 789, i64 123) ] | ||||
; CHECK-NEXT: ret void | ; CHECK-NEXT: ret void | ||||
; CHECK: guarded1: | ; CHECK: guarded1: | ||||
; CHECK-NEXT: store i32 2, i32* [[P]] | ; CHECK-NEXT: store i32 2, i32* [[P]] | ||||
; CHECK-NEXT: [[WIDENABLE_COND7:%.*]] = call i1 @llvm.experimental.widenable.condition() | ; CHECK-NEXT: [[WIDENABLE_COND7:%.*]] = call i1 @llvm.experimental.widenable.condition() | ||||
; CHECK-NEXT: [[EXIPLICIT_GUARD_COND8:%.*]] = and i1 [[COND3:%.*]], [[WIDENABLE_COND7]] | ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND8:%.*]] = and i1 [[COND3:%.*]], [[WIDENABLE_COND7]] | ||||
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND8]], label [[GUARDED5:%.*]], label [[DEOPT6:%.*]], !prof !0 | ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND8]], label [[GUARDED5:%.*]], label [[DEOPT6:%.*]], !make.implicit !0 | ||||
; CHECK: deopt6: | ; CHECK: deopt6: | ||||
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 456, i64 789) ] | ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 456, i64 789) ] | ||||
; CHECK-NEXT: ret void | ; CHECK-NEXT: ret void | ||||
; CHECK: guarded5: | ; CHECK: guarded5: | ||||
; CHECK-NEXT: store i32 3, i32* [[P]] | ; CHECK-NEXT: store i32 3, i32* [[P]] | ||||
; CHECK-NEXT: ret void | ; CHECK-NEXT: ret void | ||||
; | ; | ||||
entry: | entry: | ||||
Show All 12 Lines | |||||
; CHECK-LABEL: @split_loop( | ; CHECK-LABEL: @split_loop( | ||||
; CHECK-NEXT: entry: | ; CHECK-NEXT: entry: | ||||
; CHECK-NEXT: br label [[LOOP:%.*]] | ; CHECK-NEXT: br label [[LOOP:%.*]] | ||||
; CHECK: loop: | ; CHECK: loop: | ||||
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[GUARDED:%.*]] ] | ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[GUARDED:%.*]] ] | ||||
; CHECK-NEXT: [[GUARD_COND:%.*]] = icmp slt i32 [[IV]], [[N:%.*]] | ; CHECK-NEXT: [[GUARD_COND:%.*]] = icmp slt i32 [[IV]], [[N:%.*]] | ||||
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() | ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() | ||||
; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[GUARD_COND]], [[WIDENABLE_COND]] | ; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[GUARD_COND]], [[WIDENABLE_COND]] | ||||
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0 | ; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !make.implicit !0 | ||||
; CHECK: deopt: | ; CHECK: deopt: | ||||
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 123, i64 456) ] | ; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 123, i64 456) ] | ||||
; CHECK-NEXT: ret void | ; CHECK-NEXT: ret void | ||||
; CHECK: guarded: | ; CHECK: guarded: | ||||
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp slt i32 [[IV]], [[M:%.*]] | ; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp slt i32 [[IV]], [[M:%.*]] | ||||
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 | ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 | ||||
; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]] | ; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]] | ||||
; CHECK: exit: | ; CHECK: exit: | ||||
Show All 16 Lines |