Please use GitHub pull requests for new patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
llvm/test/Transforms/SimplifyCFG/switch_ub.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 -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s | ; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s | ||||
; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s | ; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s | ||||
declare void @foo_01() | declare void @foo_01() | ||||
declare void @foo_02() | declare void @foo_02() | ||||
declare void @foo_03() | declare void @foo_03() | ||||
; TODO: Basing on fact that load(null) is UB, we can remove edge pred->bb. | |||||
mkazantsev: You can remove this TODO as well. | |||||
define i32 @test_01(i32* %p, i32 %x, i1 %cond) { | define i32 @test_01(i32* %p, i32 %x, i1 %cond) { | ||||
; CHECK-LABEL: @test_01( | ; CHECK-LABEL: @test_01( | ||||
; CHECK-NEXT: entry: | ; CHECK-NEXT: entry: | ||||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB:%.*]], label [[PRED:%.*]] | ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB:%.*]], label [[COMMON_RET:%.*]] | ||||
; CHECK: pred: | |||||
; CHECK-NEXT: switch i32 [[X:%.*]], label [[COMMON_RET:%.*]] [ | |||||
; CHECK-NEXT: i32 42, label [[BB]] | |||||
; CHECK-NEXT: i32 123456, label [[BB]] | |||||
; CHECK-NEXT: i32 -654321, label [[BB]] | |||||
; CHECK-NEXT: ] | |||||
; CHECK: common.ret: | ; CHECK: common.ret: | ||||
; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[R:%.*]], [[BB]] ], [ 0, [[PRED]] ] | ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[R:%.*]], [[BB]] ], [ 0, [[ENTRY:%.*]] ] | ||||
; CHECK-NEXT: ret i32 [[COMMON_RET_OP]] | ; CHECK-NEXT: ret i32 [[COMMON_RET_OP]] | ||||
; CHECK: bb: | ; CHECK: bb: | ||||
; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ null, [[PRED]] ], [ null, [[PRED]] ], [ null, [[PRED]] ], [ [[P:%.*]], [[ENTRY:%.*]] ] | ; CHECK-NEXT: [[R]] = load i32, i32* [[P:%.*]], align 4 | ||||
; CHECK-NEXT: [[R]] = load i32, i32* [[PHI]], align 4 | |||||
; CHECK-NEXT: br label [[COMMON_RET]] | ; CHECK-NEXT: br label [[COMMON_RET]] | ||||
; | ; | ||||
entry: | entry: | ||||
br i1 %cond, label %bb, label %pred | br i1 %cond, label %bb, label %pred | ||||
pred: | pred: | ||||
switch i32 %x, label %other_succ [i32 42, label %bb | switch i32 %x, label %other_succ [i32 42, label %bb | ||||
i32 123456, label %bb | i32 123456, label %bb | ||||
i32 -654321, label %bb] | i32 -654321, label %bb] | ||||
bb: | bb: | ||||
%phi = phi i32* [null, %pred], [null, %pred], [null, %pred], [%p, %entry] | %phi = phi i32* [null, %pred], [null, %pred], [null, %pred], [%p, %entry] | ||||
%r = load i32, i32* %phi | %r = load i32, i32* %phi | ||||
ret i32 %r | ret i32 %r | ||||
other_succ: | other_succ: | ||||
ret i32 0 | ret i32 0 | ||||
} | } | ||||
; TODO: Basing on fact that load(null) is UB, we can remove edge pred->bb. | |||||
define i32 @test_02(i32* %p, i32 %x, i1 %cond) { | define i32 @test_02(i32* %p, i32 %x, i1 %cond) { | ||||
; CHECK-LABEL: @test_02( | ; CHECK-LABEL: @test_02( | ||||
; CHECK-NEXT: entry: | ; CHECK-NEXT: entry: | ||||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB:%.*]], label [[PRED:%.*]] | ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB:%.*]], label [[COMMON_RET:%.*]] | ||||
; CHECK: pred: | |||||
; CHECK-NEXT: switch i32 [[X:%.*]], label [[BB]] [ | |||||
; CHECK-NEXT: i32 42, label [[COMMON_RET:%.*]] | |||||
; CHECK-NEXT: i32 123456, label [[COMMON_RET]] | |||||
; CHECK-NEXT: i32 -654321, label [[COMMON_RET]] | |||||
; CHECK-NEXT: ] | |||||
; CHECK: common.ret: | ; CHECK: common.ret: | ||||
; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[R:%.*]], [[BB]] ], [ 0, [[PRED]] ], [ 0, [[PRED]] ], [ 0, [[PRED]] ] | ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[R:%.*]], [[BB]] ], [ 0, [[ENTRY:%.*]] ] | ||||
; CHECK-NEXT: ret i32 [[COMMON_RET_OP]] | ; CHECK-NEXT: ret i32 [[COMMON_RET_OP]] | ||||
; CHECK: bb: | ; CHECK: bb: | ||||
; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ null, [[PRED]] ], [ [[P:%.*]], [[ENTRY:%.*]] ] | ; CHECK-NEXT: [[R]] = load i32, i32* [[P:%.*]], align 4 | ||||
; CHECK-NEXT: [[R]] = load i32, i32* [[PHI]], align 4 | |||||
; CHECK-NEXT: br label [[COMMON_RET]] | ; CHECK-NEXT: br label [[COMMON_RET]] | ||||
; | ; | ||||
entry: | entry: | ||||
br i1 %cond, label %bb, label %pred | br i1 %cond, label %bb, label %pred | ||||
pred: | pred: | ||||
switch i32 %x, label %bb [i32 42, label %other_succ | switch i32 %x, label %bb [i32 42, label %other_succ | ||||
i32 123456, label %other_succ | i32 123456, label %other_succ | ||||
i32 -654321, label %other_succ] | i32 -654321, label %other_succ] | ||||
bb: | bb: | ||||
%phi = phi i32* [null, %pred], [%p, %entry] | %phi = phi i32* [null, %pred], [%p, %entry] | ||||
%r = load i32, i32* %phi | %r = load i32, i32* %phi | ||||
ret i32 %r | ret i32 %r | ||||
other_succ: | other_succ: | ||||
ret i32 0 | ret i32 0 | ||||
} | } | ||||
; TODO: Basing on fact that load(null) is UB, we can remove edge pred->bb. | |||||
define i32 @test_03(i32* %p, i32 %x, i1 %cond) { | define i32 @test_03(i32* %p, i32 %x, i1 %cond) { | ||||
Not Done ReplyInline ActionsPls remove TODOs mkazantsev: Pls remove TODOs | |||||
; CHECK-LABEL: @test_03( | ; CHECK-LABEL: @test_03( | ||||
; CHECK-NEXT: entry: | ; CHECK-NEXT: entry: | ||||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB:%.*]], label [[PRED:%.*]] | ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB:%.*]], label [[PRED:%.*]] | ||||
; CHECK: pred: | ; CHECK: pred: | ||||
; CHECK-NEXT: switch i32 [[X:%.*]], label [[BB]] [ | ; CHECK-NEXT: switch i32 [[X:%.*]], label [[UNREACHABLE:%.*]] [ | ||||
; CHECK-NEXT: i32 42, label [[COMMON_RET:%.*]] | ; CHECK-NEXT: i32 42, label [[COMMON_RET:%.*]] | ||||
; CHECK-NEXT: i32 123456, label [[COMMON_RET]] | ; CHECK-NEXT: i32 123456, label [[COMMON_RET]] | ||||
; CHECK-NEXT: i32 -654321, label [[COMMON_RET]] | ; CHECK-NEXT: i32 -654321, label [[COMMON_RET]] | ||||
; CHECK-NEXT: i32 1, label [[DO_1:%.*]] | ; CHECK-NEXT: i32 1, label [[DO_1:%.*]] | ||||
; CHECK-NEXT: i32 2, label [[DO_2:%.*]] | ; CHECK-NEXT: i32 2, label [[DO_2:%.*]] | ||||
; CHECK-NEXT: i32 3, label [[DO_3:%.*]] | ; CHECK-NEXT: i32 3, label [[DO_3:%.*]] | ||||
; CHECK-NEXT: ] | ; CHECK-NEXT: ] | ||||
; CHECK: common.ret: | ; CHECK: common.ret: | ||||
; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[R:%.*]], [[BB]] ], [ 1, [[DO_1]] ], [ 1, [[DO_2]] ], [ 1, [[DO_3]] ], [ 0, [[PRED]] ], [ 0, [[PRED]] ], [ 0, [[PRED]] ] | ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[R:%.*]], [[BB]] ], [ 1, [[DO_1]] ], [ 1, [[DO_2]] ], [ 1, [[DO_3]] ], [ 0, [[PRED]] ], [ 0, [[PRED]] ], [ 0, [[PRED]] ] | ||||
; CHECK-NEXT: ret i32 [[COMMON_RET_OP]] | ; CHECK-NEXT: ret i32 [[COMMON_RET_OP]] | ||||
; CHECK: unreachable: | |||||
; CHECK-NEXT: unreachable | |||||
; CHECK: bb: | ; CHECK: bb: | ||||
; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ null, [[PRED]] ], [ [[P:%.*]], [[ENTRY:%.*]] ] | ; CHECK-NEXT: [[R]] = load i32, i32* [[P:%.*]], align 4 | ||||
; CHECK-NEXT: [[R]] = load i32, i32* [[PHI]], align 4 | |||||
; CHECK-NEXT: br label [[COMMON_RET]] | ; CHECK-NEXT: br label [[COMMON_RET]] | ||||
; CHECK: do_1: | ; CHECK: do_1: | ||||
; CHECK-NEXT: call void @foo_01() | ; CHECK-NEXT: call void @foo_01() | ||||
; CHECK-NEXT: br label [[COMMON_RET]] | ; CHECK-NEXT: br label [[COMMON_RET]] | ||||
; CHECK: do_2: | ; CHECK: do_2: | ||||
; CHECK-NEXT: call void @foo_02() | ; CHECK-NEXT: call void @foo_02() | ||||
; CHECK-NEXT: br label [[COMMON_RET]] | ; CHECK-NEXT: br label [[COMMON_RET]] | ||||
; CHECK: do_3: | ; CHECK: do_3: | ||||
Show All 27 Lines | |||||
do_3: | do_3: | ||||
call void @foo_03() | call void @foo_03() | ||||
ret i32 1 | ret i32 1 | ||||
other_succ: | other_succ: | ||||
ret i32 0 | ret i32 0 | ||||
} | } | ||||
; TODO: Basing on fact that load(null) is UB, we can remove edge pred->bb. | |||||
define i32 @test_04(i32* %p, i32 %x, i1 %cond) { | define i32 @test_04(i32* %p, i32 %x, i1 %cond) { | ||||
; CHECK-LABEL: @test_04( | ; CHECK-LABEL: @test_04( | ||||
; CHECK-NEXT: entry: | ; CHECK-NEXT: entry: | ||||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB:%.*]], label [[PRED:%.*]] | ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB:%.*]], label [[PRED:%.*]] | ||||
; CHECK: pred: | ; CHECK: pred: | ||||
; CHECK-NEXT: switch i32 [[X:%.*]], label [[COMMON_RET:%.*]] [ | ; CHECK-NEXT: switch i32 [[X:%.*]], label [[COMMON_RET:%.*]] [ | ||||
; CHECK-NEXT: i32 42, label [[BB]] | |||||
; CHECK-NEXT: i32 123456, label [[BB]] | |||||
; CHECK-NEXT: i32 -654321, label [[BB]] | |||||
; CHECK-NEXT: i32 1, label [[DO_1:%.*]] | |||||
; CHECK-NEXT: i32 2, label [[DO_2:%.*]] | |||||
; CHECK-NEXT: i32 3, label [[DO_3:%.*]] | ; CHECK-NEXT: i32 3, label [[DO_3:%.*]] | ||||
; CHECK-NEXT: i32 2, label [[DO_2:%.*]] | |||||
; CHECK-NEXT: i32 1, label [[DO_1:%.*]] | |||||
; CHECK-NEXT: ] | ; CHECK-NEXT: ] | ||||
; CHECK: common.ret: | ; CHECK: common.ret: | ||||
; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[R:%.*]], [[BB]] ], [ 1, [[DO_1]] ], [ 1, [[DO_2]] ], [ 1, [[DO_3]] ], [ 0, [[PRED]] ] | ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[R:%.*]], [[BB]] ], [ 1, [[DO_1]] ], [ 1, [[DO_2]] ], [ 1, [[DO_3]] ], [ 0, [[PRED]] ] | ||||
; CHECK-NEXT: ret i32 [[COMMON_RET_OP]] | ; CHECK-NEXT: ret i32 [[COMMON_RET_OP]] | ||||
; CHECK: bb: | ; CHECK: bb: | ||||
; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ null, [[PRED]] ], [ null, [[PRED]] ], [ null, [[PRED]] ], [ [[P:%.*]], [[ENTRY:%.*]] ] | ; CHECK-NEXT: [[R]] = load i32, i32* [[P:%.*]], align 4 | ||||
; CHECK-NEXT: [[R]] = load i32, i32* [[PHI]], align 4 | |||||
; CHECK-NEXT: br label [[COMMON_RET]] | ; CHECK-NEXT: br label [[COMMON_RET]] | ||||
; CHECK: do_1: | ; CHECK: do_1: | ||||
; CHECK-NEXT: call void @foo_01() | ; CHECK-NEXT: call void @foo_01() | ||||
; CHECK-NEXT: br label [[COMMON_RET]] | ; CHECK-NEXT: br label [[COMMON_RET]] | ||||
; CHECK: do_2: | ; CHECK: do_2: | ||||
; CHECK-NEXT: call void @foo_02() | ; CHECK-NEXT: call void @foo_02() | ||||
; CHECK-NEXT: br label [[COMMON_RET]] | ; CHECK-NEXT: br label [[COMMON_RET]] | ||||
; CHECK: do_3: | ; CHECK: do_3: | ||||
Show All 34 Lines |
You can remove this TODO as well.