[llvm] 3e98b88 - [NFC][SimplifyCFG] Fix tests to use FileCheck instead of grep
Roman Lebedev via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 21 13:57:04 PDT 2021
Author: Roman Lebedev
Date: 2021-06-21T23:56:54+03:00
New Revision: 3e98b88797e52914ca67aa173aad97595fa61c73
URL: https://github.com/llvm/llvm-project/commit/3e98b88797e52914ca67aa173aad97595fa61c73
DIFF: https://github.com/llvm/llvm-project/commit/3e98b88797e52914ca67aa173aad97595fa61c73.diff
LOG: [NFC][SimplifyCFG] Fix tests to use FileCheck instead of grep
Added:
Modified:
llvm/test/Transforms/SimplifyCFG/2008-05-16-PHIBlockMerge.ll
llvm/test/Transforms/SimplifyCFG/2008-12-16-DCECond.ll
llvm/test/Transforms/SimplifyCFG/2009-05-12-externweak.ll
llvm/test/Transforms/SimplifyCFG/BrUnwind.ll
llvm/test/Transforms/SimplifyCFG/EqualPHIEdgeBlockMerge.ll
llvm/test/Transforms/SimplifyCFG/PhiBlockMerge2.ll
llvm/test/Transforms/SimplifyCFG/PhiEliminate.ll
llvm/test/Transforms/SimplifyCFG/PhiNoEliminate.ll
llvm/test/Transforms/SimplifyCFG/UncondBranchToReturn.ll
llvm/test/Transforms/SimplifyCFG/branch-cond-merge.ll
llvm/test/Transforms/SimplifyCFG/branch-cond-prop.ll
llvm/test/Transforms/SimplifyCFG/branch-fold-test.ll
llvm/test/Transforms/SimplifyCFG/branch-phi-thread.ll
llvm/test/Transforms/SimplifyCFG/dbginfo.ll
llvm/test/Transforms/SimplifyCFG/duplicate-phis.ll
llvm/test/Transforms/SimplifyCFG/hoist-common-code.ll
llvm/test/Transforms/SimplifyCFG/iterative-simplify.ll
llvm/test/Transforms/SimplifyCFG/return-merge.ll
Removed:
################################################################################
diff --git a/llvm/test/Transforms/SimplifyCFG/2008-05-16-PHIBlockMerge.ll b/llvm/test/Transforms/SimplifyCFG/2008-05-16-PHIBlockMerge.ll
index 5ee01136d33b..e5f7373f4095 100644
--- a/llvm/test/Transforms/SimplifyCFG/2008-05-16-PHIBlockMerge.ll
+++ b/llvm/test/Transforms/SimplifyCFG/2008-05-16-PHIBlockMerge.ll
@@ -1,6 +1,5 @@
-; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S > %t
-; RUN: not grep "^BB.tomerge" %t
-; RUN: grep "^BB.nomerge" %t | count 4
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
; ModuleID = '<stdin>'
declare i1 @foo()
@@ -9,123 +8,201 @@ declare i1 @bar(i32)
; This function can't be merged
define void @a() {
+; CHECK-LABEL: @a(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[BB_NOMERGE:%.*]]
+; CHECK: BB.nomerge:
+; CHECK-NEXT: [[A:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 0, [[COMMON:%.*]] ]
+; CHECK-NEXT: br label [[SUCC:%.*]]
+; CHECK: Succ:
+; CHECK-NEXT: [[B:%.*]] = phi i32 [ [[A]], [[BB_NOMERGE]] ], [ 2, [[COMMON]] ]
+; CHECK-NEXT: [[CONDE:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[CONDE]], label [[COMMON]], label [[EXIT:%.*]]
+; CHECK: Common:
+; CHECK-NEXT: [[COND:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[COND]], label [[BB_NOMERGE]], label [[SUCC]]
+; CHECK: Exit:
+; CHECK-NEXT: ret void
+;
entry:
- br label %BB.nomerge
+ br label %BB.nomerge
BB.nomerge: ; preds = %Common, %entry
- ; This phi has a conflicting value (0) with below phi (2), so blocks
- ; can't be merged.
- %a = phi i32 [ 1, %entry ], [ 0, %Common ] ; <i32> [#uses=1]
- br label %Succ
+ ; This phi has a conflicting value (0) with below phi (2), so blocks
+ ; can't be merged.
+ %a = phi i32 [ 1, %entry ], [ 0, %Common ] ; <i32> [#uses=1]
+ br label %Succ
Succ: ; preds = %Common, %BB.nomerge
- %b = phi i32 [ %a, %BB.nomerge ], [ 2, %Common ] ; <i32> [#uses=0]
- %conde = call i1 @foo( ) ; <i1> [#uses=1]
- br i1 %conde, label %Common, label %Exit
+ %b = phi i32 [ %a, %BB.nomerge ], [ 2, %Common ] ; <i32> [#uses=0]
+ %conde = call i1 @foo( ) ; <i1> [#uses=1]
+ br i1 %conde, label %Common, label %Exit
Common: ; preds = %Succ
- %cond = call i1 @foo( ) ; <i1> [#uses=1]
- br i1 %cond, label %BB.nomerge, label %Succ
+ %cond = call i1 @foo( ) ; <i1> [#uses=1]
+ br i1 %cond, label %BB.nomerge, label %Succ
Exit: ; preds = %Succ
- ret void
+ ret void
}
; This function can't be merged
define void @b() {
+; CHECK-LABEL: @b(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[BB_NOMERGE:%.*]]
+; CHECK: BB.nomerge:
+; CHECK-NEXT: br label [[SUCC:%.*]]
+; CHECK: Succ:
+; CHECK-NEXT: [[B:%.*]] = phi i32 [ 1, [[BB_NOMERGE]] ], [ 2, [[COMMON:%.*]] ]
+; CHECK-NEXT: [[CONDE:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[CONDE]], label [[COMMON]], label [[EXIT:%.*]]
+; CHECK: Common:
+; CHECK-NEXT: [[COND:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[COND]], label [[BB_NOMERGE]], label [[SUCC]]
+; CHECK: Exit:
+; CHECK-NEXT: ret void
+;
entry:
- br label %BB.nomerge
+ br label %BB.nomerge
BB.nomerge: ; preds = %Common, %entry
- br label %Succ
+ br label %Succ
Succ: ; preds = %Common, %BB.nomerge
- ; This phi has confliction values for Common and (through BB) Common,
- ; blocks can't be merged
- %b = phi i32 [ 1, %BB.nomerge ], [ 2, %Common ] ; <i32> [#uses=0]
- %conde = call i1 @foo( ) ; <i1> [#uses=1]
- br i1 %conde, label %Common, label %Exit
+ ; This phi has confliction values for Common and (through BB) Common,
+ ; blocks can't be merged
+ %b = phi i32 [ 1, %BB.nomerge ], [ 2, %Common ] ; <i32> [#uses=0]
+ %conde = call i1 @foo( ) ; <i1> [#uses=1]
+ br i1 %conde, label %Common, label %Exit
Common: ; preds = %Succ
- %cond = call i1 @foo( ) ; <i1> [#uses=1]
- br i1 %cond, label %BB.nomerge, label %Succ
+ %cond = call i1 @foo( ) ; <i1> [#uses=1]
+ br i1 %cond, label %BB.nomerge, label %Succ
Exit: ; preds = %Succ
- ret void
+ ret void
}
; This function can't be merged (for keeping canonical loop structures)
define void @c() {
+; CHECK-LABEL: @c(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[BB_NOMERGE:%.*]]
+; CHECK: BB.nomerge:
+; CHECK-NEXT: br label [[SUCC:%.*]]
+; CHECK: Succ:
+; CHECK-NEXT: [[B:%.*]] = phi i32 [ 1, [[BB_NOMERGE]] ], [ 1, [[COMMON:%.*]] ], [ 2, [[PRE_EXIT:%.*]] ]
+; CHECK-NEXT: [[CONDE:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[CONDE]], label [[COMMON]], label [[PRE_EXIT]]
+; CHECK: Common:
+; CHECK-NEXT: [[COND:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[COND]], label [[BB_NOMERGE]], label [[SUCC]]
+; CHECK: Pre-Exit:
+; CHECK-NEXT: [[COND2:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[COND2]], label [[SUCC]], label [[EXIT:%.*]]
+; CHECK: Exit:
+; CHECK-NEXT: ret void
+;
entry:
- br label %BB.nomerge
+ br label %BB.nomerge
BB.nomerge: ; preds = %Common, %entry
- br label %Succ
+ br label %Succ
Succ: ; preds = %Common, %BB.tomerge, %Pre-Exit
- ; This phi has identical values for Common and (through BB) Common,
- ; blocks can't be merged
- %b = phi i32 [ 1, %BB.nomerge ], [ 1, %Common ], [ 2, %Pre-Exit ]
- %conde = call i1 @foo( ) ; <i1> [#uses=1]
- br i1 %conde, label %Common, label %Pre-Exit
+ ; This phi has identical values for Common and (through BB) Common,
+ ; blocks can't be merged
+ %b = phi i32 [ 1, %BB.nomerge ], [ 1, %Common ], [ 2, %Pre-Exit ]
+ %conde = call i1 @foo( ) ; <i1> [#uses=1]
+ br i1 %conde, label %Common, label %Pre-Exit
Common: ; preds = %Succ
- %cond = call i1 @foo( ) ; <i1> [#uses=1]
- br i1 %cond, label %BB.nomerge, label %Succ
+ %cond = call i1 @foo( ) ; <i1> [#uses=1]
+ br i1 %cond, label %BB.nomerge, label %Succ
Pre-Exit: ; preds = %Succ
- ; This adds a backedge, so the %b phi node gets a third branch and is
- ; not completely trivial
- %cond2 = call i1 @foo( ) ; <i1> [#uses=1]
- br i1 %cond2, label %Succ, label %Exit
+ ; This adds a backedge, so the %b phi node gets a third branch and is
+ ; not completely trivial
+ %cond2 = call i1 @foo( ) ; <i1> [#uses=1]
+ br i1 %cond2, label %Succ, label %Exit
Exit: ; preds = %Pre-Exit
- ret void
+ ret void
}
; This function can't be merged (for keeping canonical loop structures)
define void @d() {
+; CHECK-LABEL: @d(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[BB_NOMERGE:%.*]]
+; CHECK: BB.nomerge:
+; CHECK-NEXT: [[A:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 0, [[COMMON:%.*]] ]
+; CHECK-NEXT: br label [[SUCC:%.*]]
+; CHECK: Succ:
+; CHECK-NEXT: [[B:%.*]] = phi i32 [ [[A]], [[BB_NOMERGE]] ], [ 0, [[COMMON]] ]
+; CHECK-NEXT: [[CONDE:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[CONDE]], label [[COMMON]], label [[EXIT:%.*]]
+; CHECK: Common:
+; CHECK-NEXT: [[COND:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[COND]], label [[BB_NOMERGE]], label [[SUCC]]
+; CHECK: Exit:
+; CHECK-NEXT: ret void
+;
entry:
- br label %BB.nomerge
+ br label %BB.nomerge
BB.nomerge: ; preds = %Common, %entry
- ; This phi has a matching value (0) with below phi (0), so blocks
- ; can be merged.
- %a = phi i32 [ 1, %entry ], [ 0, %Common ] ; <i32> [#uses=1]
- br label %Succ
+ ; This phi has a matching value (0) with below phi (0), so blocks
+ ; can be merged.
+ %a = phi i32 [ 1, %entry ], [ 0, %Common ] ; <i32> [#uses=1]
+ br label %Succ
Succ: ; preds = %Common, %BB.tomerge
- %b = phi i32 [ %a, %BB.nomerge ], [ 0, %Common ] ; <i32> [#uses=0]
- %conde = call i1 @foo( ) ; <i1> [#uses=1]
- br i1 %conde, label %Common, label %Exit
+ %b = phi i32 [ %a, %BB.nomerge ], [ 0, %Common ] ; <i32> [#uses=0]
+ %conde = call i1 @foo( ) ; <i1> [#uses=1]
+ br i1 %conde, label %Common, label %Exit
Common: ; preds = %Succ
- %cond = call i1 @foo( ) ; <i1> [#uses=1]
- br i1 %cond, label %BB.nomerge, label %Succ
+ %cond = call i1 @foo( ) ; <i1> [#uses=1]
+ br i1 %cond, label %BB.nomerge, label %Succ
Exit: ; preds = %Succ
- ret void
+ ret void
}
; This function can be merged
define void @e() {
+; CHECK-LABEL: @e(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[SUCC:%.*]]
+; CHECK: Succ:
+; CHECK-NEXT: [[A:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 0, [[USE:%.*]] ]
+; CHECK-NEXT: [[CONDE:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[CONDE]], label [[USE]], label [[EXIT:%.*]]
+; CHECK: Use:
+; CHECK-NEXT: [[COND:%.*]] = call i1 @bar(i32 [[A]])
+; CHECK-NEXT: br i1 [[COND]], label [[SUCC]], label [[EXIT]]
+; CHECK: Exit:
+; CHECK-NEXT: ret void
+;
entry:
- br label %Succ
+ br label %Succ
Succ: ; preds = %Use, %entry
- ; This phi is used somewhere else than Succ, but this should not prevent
- ; merging this block
- %a = phi i32 [ 1, %entry ], [ 0, %Use ] ; <i32> [#uses=1]
- br label %BB.tomerge
+ ; This phi is used somewhere else than Succ, but this should not prevent
+ ; merging this block
+ %a = phi i32 [ 1, %entry ], [ 0, %Use ] ; <i32> [#uses=1]
+ br label %BB.tomerge
BB.tomerge: ; preds = %BB.tomerge
- %conde = call i1 @foo( ) ; <i1> [#uses=1]
- br i1 %conde, label %Use, label %Exit
+ %conde = call i1 @foo( ) ; <i1> [#uses=1]
+ br i1 %conde, label %Use, label %Exit
Use: ; preds = %Succ
- %cond = call i1 @bar( i32 %a ) ; <i1> [#uses=1]
- br i1 %cond, label %Succ, label %Exit
+ %cond = call i1 @bar( i32 %a ) ; <i1> [#uses=1]
+ br i1 %cond, label %Succ, label %Exit
Exit: ; preds = %Use, %Succ
- ret void
+ ret void
}
diff --git a/llvm/test/Transforms/SimplifyCFG/2008-12-16-DCECond.ll b/llvm/test/Transforms/SimplifyCFG/2008-12-16-DCECond.ll
index 108fa3094add..9372fcd35bbb 100644
--- a/llvm/test/Transforms/SimplifyCFG/2008-12-16-DCECond.ll
+++ b/llvm/test/Transforms/SimplifyCFG/2008-12-16-DCECond.ll
@@ -1,43 +1,50 @@
-; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S -hoist-common-insts=true | not grep icmp
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S -hoist-common-insts=true | FileCheck %s
; ModuleID = '/tmp/x.bc'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
target triple = "i686-pc-linux-gnu"
define i32 @x(i32 %x) {
+; CHECK-LABEL: @x(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CALL:%.*]] = call i32 (...) @foo()
+; CHECK-NEXT: [[CALL9:%.*]] = call i32 (...) @bar()
+; CHECK-NEXT: ret i32 0
+;
entry:
- %cmp = icmp eq i32 %x, 8 ; <i1> [#uses=1]
- br i1 %cmp, label %ifthen, label %ifend
+ %cmp = icmp eq i32 %x, 8 ; <i1> [#uses=1]
+ br i1 %cmp, label %ifthen, label %ifend
ifthen: ; preds = %entry
- %call = call i32 (...) @foo() ; <i32> [#uses=0]
- br label %ifend
+ %call = call i32 (...) @foo() ; <i32> [#uses=0]
+ br label %ifend
ifend: ; preds = %ifthen, %entry
- %cmp2 = icmp ne i32 %x, 8 ; <i1> [#uses=1]
- br i1 %cmp2, label %ifthen3, label %ifend5
+ %cmp2 = icmp ne i32 %x, 8 ; <i1> [#uses=1]
+ br i1 %cmp2, label %ifthen3, label %ifend5
ifthen3: ; preds = %ifend
- %call4 = call i32 (...) @foo() ; <i32> [#uses=0]
- br label %ifend5
+ %call4 = call i32 (...) @foo() ; <i32> [#uses=0]
+ br label %ifend5
ifend5: ; preds = %ifthen3, %ifend
- %cmp7 = icmp eq i32 %x, 9 ; <i1> [#uses=1]
- br i1 %cmp7, label %ifthen8, label %ifend10
+ %cmp7 = icmp eq i32 %x, 9 ; <i1> [#uses=1]
+ br i1 %cmp7, label %ifthen8, label %ifend10
ifthen8: ; preds = %ifend5
- %call9 = call i32 (...) @bar() ; <i32> [#uses=0]
- br label %ifend10
+ %call9 = call i32 (...) @bar() ; <i32> [#uses=0]
+ br label %ifend10
ifend10: ; preds = %ifthen8, %ifend5
- %cmp12 = icmp ne i32 %x, 9 ; <i1> [#uses=1]
- br i1 %cmp12, label %ifthen13, label %ifend15
+ %cmp12 = icmp ne i32 %x, 9 ; <i1> [#uses=1]
+ br i1 %cmp12, label %ifthen13, label %ifend15
ifthen13: ; preds = %ifend10
- %call14 = call i32 (...) @bar() ; <i32> [#uses=0]
- br label %ifend15
+ %call14 = call i32 (...) @bar() ; <i32> [#uses=0]
+ br label %ifend15
ifend15: ; preds = %ifthen13, %ifend10
- ret i32 0
+ ret i32 0
}
declare i32 @foo(...)
diff --git a/llvm/test/Transforms/SimplifyCFG/2009-05-12-externweak.ll b/llvm/test/Transforms/SimplifyCFG/2009-05-12-externweak.ll
index a1a78d713750..c95343a3a771 100644
--- a/llvm/test/Transforms/SimplifyCFG/2009-05-12-externweak.ll
+++ b/llvm/test/Transforms/SimplifyCFG/2009-05-12-externweak.ll
@@ -1,4 +1,5 @@
-; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | not grep select
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
; ModuleID = '<stdin>'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
target triple = "i386-apple-darwin10.0"
@@ -11,37 +12,62 @@ module asm ".set _i, 0"
@ed = common global double 0.000000e+00, align 8 ; <double*> [#uses=1]
define i32 @main() nounwind ssp {
+; CHECK-LABEL: @main(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[BB4:%.*]]
+; CHECK: bb:
+; CHECK-NEXT: br i1 icmp ne (i32* @i, i32* null), label [[BB1:%.*]], label [[BB3:%.*]]
+; CHECK: bb1:
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4
+; CHECK-NEXT: br label [[BB3]]
+; CHECK: bb3:
+; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32 [ [[TMP0]], [[BB1]] ], [ 0, [[BB:%.*]] ]
+; CHECK-NEXT: store i32 [[STOREMERGE]], i32* @j, align 4
+; CHECK-NEXT: [[TMP1:%.*]] = sitofp i32 [[STOREMERGE]] to double
+; CHECK-NEXT: [[TMP2:%.*]] = call double @sin(double [[TMP1]]) #[[ATTR1:[0-9]+]]
+; CHECK-NEXT: [[TMP3:%.*]] = fadd double [[TMP2]], [[D_0:%.*]]
+; CHECK-NEXT: [[TMP4:%.*]] = add i32 [[L_0:%.*]], 1
+; CHECK-NEXT: br label [[BB4]]
+; CHECK: bb4:
+; CHECK-NEXT: [[D_0]] = phi double [ undef, [[ENTRY:%.*]] ], [ [[TMP3]], [[BB3]] ]
+; CHECK-NEXT: [[L_0]] = phi i32 [ 0, [[ENTRY]] ], [ [[TMP4]], [[BB3]] ]
+; CHECK-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[L_0]], 99
+; CHECK-NEXT: br i1 [[TMP5]], label [[BB5:%.*]], label [[BB]]
+; CHECK: bb5:
+; CHECK-NEXT: store double [[D_0]], double* @ed, align 8
+; CHECK-NEXT: ret i32 0
+;
entry:
- br label %bb4
+ br label %bb4
bb: ; preds = %bb4
- br i1 icmp ne (i32* @i, i32* null), label %bb1, label %bb2
+ br i1 icmp ne (i32* @i, i32* null), label %bb1, label %bb2
bb1: ; preds = %bb
- %0 = load i32, i32* @i, align 4 ; <i32> [#uses=1]
- br label %bb3
+ %0 = load i32, i32* @i, align 4 ; <i32> [#uses=1]
+ br label %bb3
bb2: ; preds = %bb
- br label %bb3
+ br label %bb3
bb3: ; preds = %bb2, %bb1
- %storemerge = phi i32 [ %0, %bb1 ], [ 0, %bb2 ] ; <i32> [#uses=2]
- store i32 %storemerge, i32* @j
- %1 = sitofp i32 %storemerge to double ; <double> [#uses=1]
- %2 = call double @sin(double %1) nounwind readonly ; <double> [#uses=1]
- %3 = fadd double %2, %d.0 ; <double> [#uses=1]
- %4 = add i32 %l.0, 1 ; <i32> [#uses=1]
- br label %bb4
+ %storemerge = phi i32 [ %0, %bb1 ], [ 0, %bb2 ] ; <i32> [#uses=2]
+ store i32 %storemerge, i32* @j
+ %1 = sitofp i32 %storemerge to double ; <double> [#uses=1]
+ %2 = call double @sin(double %1) nounwind readonly ; <double> [#uses=1]
+ %3 = fadd double %2, %d.0 ; <double> [#uses=1]
+ %4 = add i32 %l.0, 1 ; <i32> [#uses=1]
+ br label %bb4
bb4: ; preds = %bb3, %entry
- %d.0 = phi double [ undef, %entry ], [ %3, %bb3 ] ; <double> [#uses=2]
- %l.0 = phi i32 [ 0, %entry ], [ %4, %bb3 ] ; <i32> [#uses=2]
- %5 = icmp sgt i32 %l.0, 99 ; <i1> [#uses=1]
- br i1 %5, label %bb5, label %bb
+ %d.0 = phi double [ undef, %entry ], [ %3, %bb3 ] ; <double> [#uses=2]
+ %l.0 = phi i32 [ 0, %entry ], [ %4, %bb3 ] ; <i32> [#uses=2]
+ %5 = icmp sgt i32 %l.0, 99 ; <i1> [#uses=1]
+ br i1 %5, label %bb5, label %bb
bb5: ; preds = %bb4
- store double %d.0, double* @ed, align 8
- ret i32 0
+ store double %d.0, double* @ed, align 8
+ ret i32 0
}
declare double @sin(double) nounwind readonly
diff --git a/llvm/test/Transforms/SimplifyCFG/BrUnwind.ll b/llvm/test/Transforms/SimplifyCFG/BrUnwind.ll
index c40f5513cebf..b3324b628502 100644
--- a/llvm/test/Transforms/SimplifyCFG/BrUnwind.ll
+++ b/llvm/test/Transforms/SimplifyCFG/BrUnwind.ll
@@ -1,15 +1,20 @@
-; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -hoist-common-insts=true -S | \
-; RUN: not grep "br label"
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -hoist-common-insts=true -S | FileCheck %s
define void @test(i1 %C) {
- br i1 %C, label %A, label %B
+; CHECK-LABEL: @test(
+; CHECK-NEXT: X:
+; CHECK-NEXT: call void @test(i1 [[C:%.*]])
+; CHECK-NEXT: ret void
+;
+ br i1 %C, label %A, label %B
A: ; preds = %0
- call void @test( i1 %C )
- br label %X
+ call void @test( i1 %C )
+ br label %X
B: ; preds = %0
- call void @test( i1 %C )
- br label %X
+ call void @test( i1 %C )
+ br label %X
X: ; preds = %B, %A
- ret void
+ ret void
}
diff --git a/llvm/test/Transforms/SimplifyCFG/EqualPHIEdgeBlockMerge.ll b/llvm/test/Transforms/SimplifyCFG/EqualPHIEdgeBlockMerge.ll
index 8d1a342baaf9..96cd0469a38d 100644
--- a/llvm/test/Transforms/SimplifyCFG/EqualPHIEdgeBlockMerge.ll
+++ b/llvm/test/Transforms/SimplifyCFG/EqualPHIEdgeBlockMerge.ll
@@ -1,11 +1,7 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Test merging of blocks with phi nodes.
;
-; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S > %t
-; RUN: not grep N: %t
-; RUN: not grep X: %t
-; RUN: not grep 'switch i32[^U]+%U' %t
-; RUN: not grep "^BB.tomerge" %t
-; RUN: grep "^BB.nomerge" %t | count 4
+; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
;
; ModuleID = '<stdin>'
@@ -14,26 +10,38 @@ declare i1 @foo()
declare i1 @bar(i32)
define i32 @test(i1 %a) {
+; CHECK-LABEL: @test(
+; CHECK-NEXT: Q:
+; CHECK-NEXT: [[R:%.*]] = add i32 2, 1
+; CHECK-NEXT: ret i32 [[R]]
+;
Q:
- br i1 %a, label %N, label %M
+ br i1 %a, label %N, label %M
N: ; preds = %Q
- br label %M
+ br label %M
M: ; preds = %N, %Q
- ; It's ok to merge N and M because the incoming values for W are the
- ; same for both cases...
- %W = phi i32 [ 2, %N ], [ 2, %Q ] ; <i32> [#uses=1]
- %R = add i32 %W, 1 ; <i32> [#uses=1]
- ret i32 %R
+ ; It's ok to merge N and M because the incoming values for W are the
+ ; same for both cases...
+ %W = phi i32 [ 2, %N ], [ 2, %Q ] ; <i32> [#uses=1]
+ %R = add i32 %W, 1 ; <i32> [#uses=1]
+ ret i32 %R
}
; Test merging of blocks with phi nodes where at least one incoming value
; in the successor is undef.
define i8 @testundef(i32 %u) {
+; CHECK-LABEL: @testundef(
+; CHECK-NEXT: R:
+; CHECK-NEXT: [[U_OFF:%.*]] = add i32 [[U:%.*]], -1
+; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[U_OFF]], 2
+; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[SWITCH]], i8 1, i8 0
+; CHECK-NEXT: ret i8 [[SPEC_SELECT]]
+;
R:
switch i32 %u, label %U [
- i32 0, label %S
- i32 1, label %T
- i32 2, label %T
+ i32 0, label %S
+ i32 1, label %T
+ i32 2, label %T
]
S: ; preds = %R
@@ -54,12 +62,22 @@ U: ; preds = %T, %S, %R
; Test merging of blocks with phi nodes where at least one incoming value
; in the successor is undef.
define i8 @testundef2(i32 %u, i32* %A) {
+; CHECK-LABEL: @testundef2(
+; CHECK-NEXT: V:
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[U:%.*]], 3
+; CHECK-NEXT: br i1 [[COND]], label [[Z:%.*]], label [[U:%.*]]
+; CHECK: Z:
+; CHECK-NEXT: store i32 0, i32* [[A:%.*]], align 4
+; CHECK-NEXT: br label [[U]]
+; CHECK: U:
+; CHECK-NEXT: ret i8 1
+;
V:
switch i32 %u, label %U [
- i32 0, label %W
- i32 1, label %X
- i32 2, label %X
- i32 3, label %Z
+ i32 0, label %W
+ i32 1, label %X
+ i32 2, label %X
+ i32 3, label %Z
]
W: ; preds = %V
@@ -83,12 +101,28 @@ U: ; preds = %X, %W, %V
}
define i8 @testmergesome(i32 %u, i32* %A) {
+; CHECK-LABEL: @testmergesome(
+; CHECK-NEXT: V:
+; CHECK-NEXT: switch i32 [[U:%.*]], label [[Y:%.*]] [
+; CHECK-NEXT: i32 0, label [[W:%.*]]
+; CHECK-NEXT: i32 3, label [[Z:%.*]]
+; CHECK-NEXT: ]
+; CHECK: W:
+; CHECK-NEXT: store i32 1, i32* [[A:%.*]], align 4
+; CHECK-NEXT: br label [[Y]]
+; CHECK: Z:
+; CHECK-NEXT: store i32 0, i32* [[A]], align 4
+; CHECK-NEXT: br label [[Y]]
+; CHECK: Y:
+; CHECK-NEXT: [[VAL_0:%.*]] = phi i8 [ 2, [[W]] ], [ 1, [[Z]] ], [ 1, [[V:%.*]] ]
+; CHECK-NEXT: ret i8 [[VAL_0]]
+;
V:
switch i32 %u, label %Y [
- i32 0, label %W
- i32 1, label %X
- i32 2, label %X
- i32 3, label %Z
+ i32 0, label %W
+ i32 1, label %X
+ i32 2, label %X
+ i32 3, label %Z
]
W: ; preds = %V
@@ -111,12 +145,26 @@ Y: ; preds = %X, %W, %V
define i8 @testmergesome2(i32 %u, i32* %A) {
+; CHECK-LABEL: @testmergesome2(
+; CHECK-NEXT: V:
+; CHECK-NEXT: switch i32 [[U:%.*]], label [[W:%.*]] [
+; CHECK-NEXT: i32 4, label [[Y:%.*]]
+; CHECK-NEXT: i32 1, label [[Y]]
+; CHECK-NEXT: i32 2, label [[Y]]
+; CHECK-NEXT: ]
+; CHECK: W:
+; CHECK-NEXT: store i32 1, i32* [[A:%.*]], align 4
+; CHECK-NEXT: br label [[Y]]
+; CHECK: Y:
+; CHECK-NEXT: [[VAL_0:%.*]] = phi i8 [ 1, [[V:%.*]] ], [ 2, [[W]] ], [ 1, [[V]] ], [ 1, [[V]] ]
+; CHECK-NEXT: ret i8 [[VAL_0]]
+;
V:
switch i32 %u, label %W [
- i32 0, label %W
- i32 1, label %Y
- i32 2, label %X
- i32 4, label %Y
+ i32 0, label %W
+ i32 1, label %Y
+ i32 2, label %X
+ i32 4, label %Y
]
W: ; preds = %V
@@ -134,123 +182,201 @@ Y: ; preds = %X, %W, %V
; This function can't be merged
define void @a() {
+; CHECK-LABEL: @a(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[BB_NOMERGE:%.*]]
+; CHECK: BB.nomerge:
+; CHECK-NEXT: [[A:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 0, [[COMMON:%.*]] ]
+; CHECK-NEXT: br label [[SUCC:%.*]]
+; CHECK: Succ:
+; CHECK-NEXT: [[B:%.*]] = phi i32 [ [[A]], [[BB_NOMERGE]] ], [ 2, [[COMMON]] ]
+; CHECK-NEXT: [[CONDE:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[CONDE]], label [[COMMON]], label [[EXIT:%.*]]
+; CHECK: Common:
+; CHECK-NEXT: [[COND:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[COND]], label [[BB_NOMERGE]], label [[SUCC]]
+; CHECK: Exit:
+; CHECK-NEXT: ret void
+;
entry:
- br label %BB.nomerge
+ br label %BB.nomerge
BB.nomerge: ; preds = %Common, %entry
- ; This phi has a conflicting value (0) with below phi (2), so blocks
- ; can't be merged.
- %a = phi i32 [ 1, %entry ], [ 0, %Common ] ; <i32> [#uses=1]
- br label %Succ
+ ; This phi has a conflicting value (0) with below phi (2), so blocks
+ ; can't be merged.
+ %a = phi i32 [ 1, %entry ], [ 0, %Common ] ; <i32> [#uses=1]
+ br label %Succ
Succ: ; preds = %Common, %BB.nomerge
- %b = phi i32 [ %a, %BB.nomerge ], [ 2, %Common ] ; <i32> [#uses=0]
- %conde = call i1 @foo( ) ; <i1> [#uses=1]
- br i1 %conde, label %Common, label %Exit
+ %b = phi i32 [ %a, %BB.nomerge ], [ 2, %Common ] ; <i32> [#uses=0]
+ %conde = call i1 @foo( ) ; <i1> [#uses=1]
+ br i1 %conde, label %Common, label %Exit
Common: ; preds = %Succ
- %cond = call i1 @foo( ) ; <i1> [#uses=1]
- br i1 %cond, label %BB.nomerge, label %Succ
+ %cond = call i1 @foo( ) ; <i1> [#uses=1]
+ br i1 %cond, label %BB.nomerge, label %Succ
Exit: ; preds = %Succ
- ret void
+ ret void
}
; This function can't be merged
define void @b() {
+; CHECK-LABEL: @b(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[BB_NOMERGE:%.*]]
+; CHECK: BB.nomerge:
+; CHECK-NEXT: br label [[SUCC:%.*]]
+; CHECK: Succ:
+; CHECK-NEXT: [[B:%.*]] = phi i32 [ 1, [[BB_NOMERGE]] ], [ 2, [[COMMON:%.*]] ]
+; CHECK-NEXT: [[CONDE:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[CONDE]], label [[COMMON]], label [[EXIT:%.*]]
+; CHECK: Common:
+; CHECK-NEXT: [[COND:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[COND]], label [[BB_NOMERGE]], label [[SUCC]]
+; CHECK: Exit:
+; CHECK-NEXT: ret void
+;
entry:
- br label %BB.nomerge
+ br label %BB.nomerge
BB.nomerge: ; preds = %Common, %entry
- br label %Succ
+ br label %Succ
Succ: ; preds = %Common, %BB.nomerge
- ; This phi has confliction values for Common and (through BB) Common,
- ; blocks can't be merged
- %b = phi i32 [ 1, %BB.nomerge ], [ 2, %Common ] ; <i32> [#uses=0]
- %conde = call i1 @foo( ) ; <i1> [#uses=1]
- br i1 %conde, label %Common, label %Exit
+ ; This phi has confliction values for Common and (through BB) Common,
+ ; blocks can't be merged
+ %b = phi i32 [ 1, %BB.nomerge ], [ 2, %Common ] ; <i32> [#uses=0]
+ %conde = call i1 @foo( ) ; <i1> [#uses=1]
+ br i1 %conde, label %Common, label %Exit
Common: ; preds = %Succ
- %cond = call i1 @foo( ) ; <i1> [#uses=1]
- br i1 %cond, label %BB.nomerge, label %Succ
+ %cond = call i1 @foo( ) ; <i1> [#uses=1]
+ br i1 %cond, label %BB.nomerge, label %Succ
Exit: ; preds = %Succ
- ret void
+ ret void
}
; This function can't be merged (for keeping canonical loop structures)
define void @c() {
+; CHECK-LABEL: @c(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[BB_NOMERGE:%.*]]
+; CHECK: BB.nomerge:
+; CHECK-NEXT: br label [[SUCC:%.*]]
+; CHECK: Succ:
+; CHECK-NEXT: [[B:%.*]] = phi i32 [ 1, [[BB_NOMERGE]] ], [ 1, [[COMMON:%.*]] ], [ 2, [[PRE_EXIT:%.*]] ]
+; CHECK-NEXT: [[CONDE:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[CONDE]], label [[COMMON]], label [[PRE_EXIT]]
+; CHECK: Common:
+; CHECK-NEXT: [[COND:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[COND]], label [[BB_NOMERGE]], label [[SUCC]]
+; CHECK: Pre-Exit:
+; CHECK-NEXT: [[COND2:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[COND2]], label [[SUCC]], label [[EXIT:%.*]]
+; CHECK: Exit:
+; CHECK-NEXT: ret void
+;
entry:
- br label %BB.nomerge
+ br label %BB.nomerge
BB.nomerge: ; preds = %Common, %entry
- br label %Succ
+ br label %Succ
Succ: ; preds = %Common, %BB.tomerge, %Pre-Exit
- ; This phi has identical values for Common and (through BB) Common,
- ; blocks can't be merged
- %b = phi i32 [ 1, %BB.nomerge ], [ 1, %Common ], [ 2, %Pre-Exit ]
- %conde = call i1 @foo( ) ; <i1> [#uses=1]
- br i1 %conde, label %Common, label %Pre-Exit
+ ; This phi has identical values for Common and (through BB) Common,
+ ; blocks can't be merged
+ %b = phi i32 [ 1, %BB.nomerge ], [ 1, %Common ], [ 2, %Pre-Exit ]
+ %conde = call i1 @foo( ) ; <i1> [#uses=1]
+ br i1 %conde, label %Common, label %Pre-Exit
Common: ; preds = %Succ
- %cond = call i1 @foo( ) ; <i1> [#uses=1]
- br i1 %cond, label %BB.nomerge, label %Succ
+ %cond = call i1 @foo( ) ; <i1> [#uses=1]
+ br i1 %cond, label %BB.nomerge, label %Succ
Pre-Exit: ; preds = %Succ
- ; This adds a backedge, so the %b phi node gets a third branch and is
- ; not completely trivial
- %cond2 = call i1 @foo( ) ; <i1> [#uses=1]
- br i1 %cond2, label %Succ, label %Exit
+ ; This adds a backedge, so the %b phi node gets a third branch and is
+ ; not completely trivial
+ %cond2 = call i1 @foo( ) ; <i1> [#uses=1]
+ br i1 %cond2, label %Succ, label %Exit
Exit: ; preds = %Pre-Exit
- ret void
+ ret void
}
; This function can't be merged (for keeping canonical loop structures)
define void @d() {
+; CHECK-LABEL: @d(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[BB_NOMERGE:%.*]]
+; CHECK: BB.nomerge:
+; CHECK-NEXT: [[A:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 0, [[COMMON:%.*]] ]
+; CHECK-NEXT: br label [[SUCC:%.*]]
+; CHECK: Succ:
+; CHECK-NEXT: [[B:%.*]] = phi i32 [ [[A]], [[BB_NOMERGE]] ], [ 0, [[COMMON]] ]
+; CHECK-NEXT: [[CONDE:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[CONDE]], label [[COMMON]], label [[EXIT:%.*]]
+; CHECK: Common:
+; CHECK-NEXT: [[COND:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[COND]], label [[BB_NOMERGE]], label [[SUCC]]
+; CHECK: Exit:
+; CHECK-NEXT: ret void
+;
entry:
- br label %BB.nomerge
+ br label %BB.nomerge
BB.nomerge: ; preds = %Common, %entry
- ; This phi has a matching value (0) with below phi (0), so blocks
- ; can be merged.
- %a = phi i32 [ 1, %entry ], [ 0, %Common ] ; <i32> [#uses=1]
- br label %Succ
+ ; This phi has a matching value (0) with below phi (0), so blocks
+ ; can be merged.
+ %a = phi i32 [ 1, %entry ], [ 0, %Common ] ; <i32> [#uses=1]
+ br label %Succ
Succ: ; preds = %Common, %BB.tomerge
- %b = phi i32 [ %a, %BB.nomerge ], [ 0, %Common ] ; <i32> [#uses=0]
- %conde = call i1 @foo( ) ; <i1> [#uses=1]
- br i1 %conde, label %Common, label %Exit
+ %b = phi i32 [ %a, %BB.nomerge ], [ 0, %Common ] ; <i32> [#uses=0]
+ %conde = call i1 @foo( ) ; <i1> [#uses=1]
+ br i1 %conde, label %Common, label %Exit
Common: ; preds = %Succ
- %cond = call i1 @foo( ) ; <i1> [#uses=1]
- br i1 %cond, label %BB.nomerge, label %Succ
+ %cond = call i1 @foo( ) ; <i1> [#uses=1]
+ br i1 %cond, label %BB.nomerge, label %Succ
Exit: ; preds = %Succ
- ret void
+ ret void
}
; This function can be merged
define void @e() {
+; CHECK-LABEL: @e(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[SUCC:%.*]]
+; CHECK: Succ:
+; CHECK-NEXT: [[A:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 0, [[USE:%.*]] ]
+; CHECK-NEXT: [[CONDE:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[CONDE]], label [[USE]], label [[EXIT:%.*]]
+; CHECK: Use:
+; CHECK-NEXT: [[COND:%.*]] = call i1 @bar(i32 [[A]])
+; CHECK-NEXT: br i1 [[COND]], label [[SUCC]], label [[EXIT]]
+; CHECK: Exit:
+; CHECK-NEXT: ret void
+;
entry:
- br label %Succ
+ br label %Succ
Succ: ; preds = %Use, %entry
- ; This phi is used somewhere else than Succ, but this should not prevent
- ; merging this block
- %a = phi i32 [ 1, %entry ], [ 0, %Use ] ; <i32> [#uses=1]
- br label %BB.tomerge
+ ; This phi is used somewhere else than Succ, but this should not prevent
+ ; merging this block
+ %a = phi i32 [ 1, %entry ], [ 0, %Use ] ; <i32> [#uses=1]
+ br label %BB.tomerge
BB.tomerge: ; preds = %Succ
- %conde = call i1 @foo( ) ; <i1> [#uses=1]
- br i1 %conde, label %Use, label %Exit
+ %conde = call i1 @foo( ) ; <i1> [#uses=1]
+ br i1 %conde, label %Use, label %Exit
Use: ; preds = %Succ
- %cond = call i1 @bar( i32 %a ) ; <i1> [#uses=1]
- br i1 %cond, label %Succ, label %Exit
+ %cond = call i1 @bar( i32 %a ) ; <i1> [#uses=1]
+ br i1 %cond, label %Succ, label %Exit
Exit: ; preds = %Use, %Succ
- ret void
+ ret void
}
diff --git a/llvm/test/Transforms/SimplifyCFG/PhiBlockMerge2.ll b/llvm/test/Transforms/SimplifyCFG/PhiBlockMerge2.ll
index 593f10fb925a..58cc21da2b6c 100644
--- a/llvm/test/Transforms/SimplifyCFG/PhiBlockMerge2.ll
+++ b/llvm/test/Transforms/SimplifyCFG/PhiBlockMerge2.ll
@@ -1,27 +1,40 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Test merging of blocks that only have PHI nodes in them. This tests the case
; where the mergedinto block doesn't have any PHI nodes, and is in fact
; dominated by the block-to-be-eliminated
;
-; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | not grep N:
+; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
;
declare i1 @foo()
define i32 @test(i1 %a, i1 %b) {
- %c = call i1 @foo()
- br i1 %c, label %N, label %P
+; CHECK-LABEL: @test(
+; CHECK-NEXT: [[C:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[C]], label [[M:%.*]], label [[P:%.*]]
+; CHECK: P:
+; CHECK-NEXT: [[D:%.*]] = call i1 @foo()
+; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[D]], i32 2, i32 1
+; CHECK-NEXT: br label [[M]]
+; CHECK: M:
+; CHECK-NEXT: [[W:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ [[SPEC_SELECT]], [[P]] ]
+; CHECK-NEXT: [[R:%.*]] = add i32 [[W]], 1
+; CHECK-NEXT: ret i32 [[R]]
+;
+ %c = call i1 @foo()
+ br i1 %c, label %N, label %P
P:
- %d = call i1 @foo()
- br i1 %d, label %N, label %Q
+ %d = call i1 @foo()
+ br i1 %d, label %N, label %Q
Q:
- br label %N
+ br label %N
N:
- %W = phi i32 [0, %0], [1, %Q], [2, %P]
- ; This block should be foldable into M
- br label %M
+ %W = phi i32 [0, %0], [1, %Q], [2, %P]
+ ; This block should be foldable into M
+ br label %M
M:
- %R = add i32 %W, 1
- ret i32 %R
+ %R = add i32 %W, 1
+ ret i32 %R
}
diff --git a/llvm/test/Transforms/SimplifyCFG/PhiEliminate.ll b/llvm/test/Transforms/SimplifyCFG/PhiEliminate.ll
index ee3814d62c06..5bb4e918c865 100644
--- a/llvm/test/Transforms/SimplifyCFG/PhiEliminate.ll
+++ b/llvm/test/Transforms/SimplifyCFG/PhiEliminate.ll
@@ -1,11 +1,10 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Test a bunch of cases where the cfg simplification code should
; be able to fold PHI nodes into computation in common cases. Folding the PHI
; nodes away allows the branches to be eliminated, performing a simple form of
; 'if conversion'.
-; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S > %t.xform
-; RUN: not grep phi %t.xform
-; RUN: grep ret %t.xform
+; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
declare void @use(i1)
@@ -14,14 +13,22 @@ declare void @use.upgrd.1(i32)
define void @test(i1 %c, i32 %V, i32 %V2) {
; <label>:0
- br i1 %c, label %T, label %F
+; CHECK-LABEL: @test(
+; CHECK-NEXT: F:
+; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[C:%.*]], i1 false, i1 true
+; CHECK-NEXT: [[SPEC_SELECT1:%.*]] = select i1 [[C]], i32 0, i32 [[V:%.*]]
+; CHECK-NEXT: call void @use(i1 [[SPEC_SELECT]])
+; CHECK-NEXT: call void @use.upgrd.1(i32 [[SPEC_SELECT1]])
+; CHECK-NEXT: ret void
+;
+ br i1 %c, label %T, label %F
T: ; preds = %0
- br label %F
+ br label %F
F: ; preds = %T, %0
- %B1 = phi i1 [ true, %0 ], [ false, %T ] ; <i1> [#uses=1]
- %I6 = phi i32 [ %V, %0 ], [ 0, %T ] ; <i32> [#uses=1]
- call void @use( i1 %B1 )
- call void @use.upgrd.1( i32 %I6 )
- ret void
+ %B1 = phi i1 [ true, %0 ], [ false, %T ] ; <i1> [#uses=1]
+ %I6 = phi i32 [ %V, %0 ], [ 0, %T ] ; <i32> [#uses=1]
+ call void @use( i1 %B1 )
+ call void @use.upgrd.1( i32 %I6 )
+ ret void
}
diff --git a/llvm/test/Transforms/SimplifyCFG/PhiNoEliminate.ll b/llvm/test/Transforms/SimplifyCFG/PhiNoEliminate.ll
index 425acfba39ce..825c44ece080 100644
--- a/llvm/test/Transforms/SimplifyCFG/PhiNoEliminate.ll
+++ b/llvm/test/Transforms/SimplifyCFG/PhiNoEliminate.ll
@@ -1,27 +1,44 @@
-; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | \
-; RUN: not grep select
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
;; The PHI node in this example should not be turned into a select, as we are
;; not able to ifcvt the entire block. As such, converting to a select just
;; introduces inefficiency without saving copies.
define i32 @bar(i1 %C) {
+; CHECK-LABEL: @bar(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[ENDIF:%.*]]
+; CHECK: then:
+; CHECK-NEXT: [[TMP_3:%.*]] = call i32 @qux()
+; CHECK-NEXT: br label [[ENDIF]]
+; CHECK: endif:
+; CHECK-NEXT: [[R:%.*]] = phi i32 [ 123, [[ENTRY:%.*]] ], [ 12312, [[THEN]] ]
+; CHECK-NEXT: [[TMP0:%.*]] = call i32 @qux()
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @qux()
+; CHECK-NEXT: [[TMP2:%.*]] = call i32 @qux()
+; CHECK-NEXT: [[TMP3:%.*]] = call i32 @qux()
+; CHECK-NEXT: [[TMP4:%.*]] = call i32 @qux()
+; CHECK-NEXT: [[TMP5:%.*]] = call i32 @qux()
+; CHECK-NEXT: [[TMP6:%.*]] = call i32 @qux()
+; CHECK-NEXT: ret i32 [[R]]
+;
entry:
- br i1 %C, label %then, label %endif
+ br i1 %C, label %then, label %endif
then: ; preds = %entry
- %tmp.3 = call i32 @qux( ) ; <i32> [#uses=0]
- br label %endif
+ %tmp.3 = call i32 @qux( ) ; <i32> [#uses=0]
+ br label %endif
endif: ; preds = %then, %entry
- %R = phi i32 [ 123, %entry ], [ 12312, %then ] ; <i32> [#uses=1]
- ;; stuff to disable tail duplication
- call i32 @qux( ) ; <i32>:0 [#uses=0]
- call i32 @qux( ) ; <i32>:1 [#uses=0]
- call i32 @qux( ) ; <i32>:2 [#uses=0]
- call i32 @qux( ) ; <i32>:3 [#uses=0]
- call i32 @qux( ) ; <i32>:4 [#uses=0]
- call i32 @qux( ) ; <i32>:5 [#uses=0]
- call i32 @qux( ) ; <i32>:6 [#uses=0]
- ret i32 %R
+ %R = phi i32 [ 123, %entry ], [ 12312, %then ] ; <i32> [#uses=1]
+ ;; stuff to disable tail duplication
+ call i32 @qux( ) ; <i32>:0 [#uses=0]
+ call i32 @qux( ) ; <i32>:1 [#uses=0]
+ call i32 @qux( ) ; <i32>:2 [#uses=0]
+ call i32 @qux( ) ; <i32>:3 [#uses=0]
+ call i32 @qux( ) ; <i32>:4 [#uses=0]
+ call i32 @qux( ) ; <i32>:5 [#uses=0]
+ call i32 @qux( ) ; <i32>:6 [#uses=0]
+ ret i32 %R
}
declare i32 @qux()
diff --git a/llvm/test/Transforms/SimplifyCFG/UncondBranchToReturn.ll b/llvm/test/Transforms/SimplifyCFG/UncondBranchToReturn.ll
index 122368406118..7f15023da6a3 100644
--- a/llvm/test/Transforms/SimplifyCFG/UncondBranchToReturn.ll
+++ b/llvm/test/Transforms/SimplifyCFG/UncondBranchToReturn.ll
@@ -1,19 +1,24 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; The unify-function-exit-nodes pass often makes basic blocks that just contain
; a PHI node and a return. Make sure the simplify cfg can straighten out this
; important case. This is basically the most trivial form of tail-duplication.
-; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -hoist-common-insts=true -S | \
-; RUN: not grep "br label"
+; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -hoist-common-insts=true -S | FileCheck %s
define i32 @test(i1 %B, i32 %A, i32 %B.upgrd.1) {
- br i1 %B, label %T, label %F
+; CHECK-LABEL: @test(
+; CHECK-NEXT: ret:
+; CHECK-NEXT: [[B_UPGRD_1_A:%.*]] = select i1 [[B:%.*]], i32 [[B_UPGRD_1:%.*]], i32 [[A:%.*]]
+; CHECK-NEXT: ret i32 [[B_UPGRD_1_A]]
+;
+ br i1 %B, label %T, label %F
T: ; preds = %0
- br label %ret
+ br label %ret
F: ; preds = %0
- br label %ret
+ br label %ret
ret: ; preds = %F, %T
- %X = phi i32 [ %A, %F ], [ %B.upgrd.1, %T ] ; <i32> [#uses=1]
- ret i32 %X
+ %X = phi i32 [ %A, %F ], [ %B.upgrd.1, %T ] ; <i32> [#uses=1]
+ ret i32 %X
}
@@ -21,13 +26,18 @@ ret: ; preds = %F, %T
; as well, even if the return block is shared and the source blocks are
; non-empty.
define i32 @test2(i1 %B, i32 %A, i32 %B.upgrd.2) {
- br i1 %B, label %T, label %F
+; CHECK-LABEL: @test2(
+; CHECK-NEXT: ret:
+; CHECK-NEXT: [[TMP0:%.*]] = call i32 @test(i1 true, i32 5, i32 8)
+; CHECK-NEXT: ret i32 [[A:%.*]]
+;
+ br i1 %B, label %T, label %F
T: ; preds = %0
- call i32 @test( i1 true, i32 5, i32 8 ) ; <i32>:1 [#uses=0]
- br label %ret
+ call i32 @test( i1 true, i32 5, i32 8 ) ; <i32>:1 [#uses=0]
+ br label %ret
F: ; preds = %0
- call i32 @test( i1 true, i32 5, i32 8 ) ; <i32>:2 [#uses=0]
- br label %ret
+ call i32 @test( i1 true, i32 5, i32 8 ) ; <i32>:2 [#uses=0]
+ br label %ret
ret: ; preds = %F, %T
- ret i32 %A
+ ret i32 %A
}
diff --git a/llvm/test/Transforms/SimplifyCFG/branch-cond-merge.ll b/llvm/test/Transforms/SimplifyCFG/branch-cond-merge.ll
index 19540d842ee4..23206c0dfc7a 100644
--- a/llvm/test/Transforms/SimplifyCFG/branch-cond-merge.ll
+++ b/llvm/test/Transforms/SimplifyCFG/branch-cond-merge.ll
@@ -1,19 +1,24 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -instcombine \
-; RUN: -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | not grep call
+; RUN: -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
declare void @bar()
define void @test(i32 %X, i32 %Y) {
+; CHECK-LABEL: @test(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret void
+;
entry:
- %tmp.2 = icmp ne i32 %X, %Y ; <i1> [#uses=1]
- br i1 %tmp.2, label %shortcirc_next, label %UnifiedReturnBlock
+ %tmp.2 = icmp ne i32 %X, %Y ; <i1> [#uses=1]
+ br i1 %tmp.2, label %shortcirc_next, label %UnifiedReturnBlock
shortcirc_next: ; preds = %entry
- %tmp.3 = icmp ne i32 %X, %Y ; <i1> [#uses=1]
- br i1 %tmp.3, label %UnifiedReturnBlock, label %then
+ %tmp.3 = icmp ne i32 %X, %Y ; <i1> [#uses=1]
+ br i1 %tmp.3, label %UnifiedReturnBlock, label %then
then: ; preds = %shortcirc_next
- call void @bar( )
- ret void
+ call void @bar( )
+ ret void
UnifiedReturnBlock: ; preds = %shortcirc_next, %entry
- ret void
+ ret void
}
diff --git a/llvm/test/Transforms/SimplifyCFG/branch-cond-prop.ll b/llvm/test/Transforms/SimplifyCFG/branch-cond-prop.ll
index e8e3ca3263fb..aa09394ff8cb 100644
--- a/llvm/test/Transforms/SimplifyCFG/branch-cond-prop.ll
+++ b/llvm/test/Transforms/SimplifyCFG/branch-cond-prop.ll
@@ -1,17 +1,23 @@
-; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | not grep call
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
declare void @bar()
define void @test(i32 %X, i32 %Y) {
+; CHECK-LABEL: @test(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP_2:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: ret void
+;
entry:
- %tmp.2 = icmp slt i32 %X, %Y ; <i1> [#uses=2]
- br i1 %tmp.2, label %shortcirc_next, label %UnifiedReturnBlock
+ %tmp.2 = icmp slt i32 %X, %Y ; <i1> [#uses=2]
+ br i1 %tmp.2, label %shortcirc_next, label %UnifiedReturnBlock
shortcirc_next: ; preds = %entry
- br i1 %tmp.2, label %UnifiedReturnBlock, label %then
+ br i1 %tmp.2, label %UnifiedReturnBlock, label %then
then: ; preds = %shortcirc_next
- call void @bar( )
- ret void
+ call void @bar( )
+ ret void
UnifiedReturnBlock: ; preds = %shortcirc_next, %entry
- ret void
+ ret void
}
diff --git a/llvm/test/Transforms/SimplifyCFG/branch-fold-test.ll b/llvm/test/Transforms/SimplifyCFG/branch-fold-test.ll
index efb0ca6d8b72..b5a625fc9235 100644
--- a/llvm/test/Transforms/SimplifyCFG/branch-fold-test.ll
+++ b/llvm/test/Transforms/SimplifyCFG/branch-fold-test.ll
@@ -1,17 +1,24 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; This test ensures that the simplifycfg pass continues to constant fold
; terminator instructions.
-; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | not grep br
+; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
define i32 @test(i32 %A, i32 %B) {
+; CHECK-LABEL: @test(
+; CHECK-NEXT: J:
+; CHECK-NEXT: [[C:%.*]] = add i32 [[A:%.*]], 12
+; CHECK-NEXT: [[D:%.*]] = add i32 [[C]], [[B:%.*]]
+; CHECK-NEXT: ret i32 [[D]]
+;
J:
- %C = add i32 %A, 12 ; <i32> [#uses=2]
- br i1 true, label %L, label %K
+ %C = add i32 %A, 12 ; <i32> [#uses=2]
+ br i1 true, label %L, label %K
L: ; preds = %J
- %D = add i32 %C, %B ; <i32> [#uses=1]
- ret i32 %D
+ %D = add i32 %C, %B ; <i32> [#uses=1]
+ ret i32 %D
K: ; preds = %J
- %E = add i32 %C, %B ; <i32> [#uses=1]
- ret i32 %E
+ %E = add i32 %C, %B ; <i32> [#uses=1]
+ ret i32 %E
}
diff --git a/llvm/test/Transforms/SimplifyCFG/branch-phi-thread.ll b/llvm/test/Transforms/SimplifyCFG/branch-phi-thread.ll
index 366c2fb44b8c..c43ac970d8d3 100644
--- a/llvm/test/Transforms/SimplifyCFG/branch-phi-thread.ll
+++ b/llvm/test/Transforms/SimplifyCFG/branch-phi-thread.ll
@@ -1,6 +1,5 @@
-; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -adce -S | \
-; RUN: not grep "call void @f1"
-; END.
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -adce -S | FileCheck %s
declare void @f1()
@@ -11,56 +10,92 @@ declare void @f3()
declare void @f4()
define i32 @test1(i32 %X, i1 %D) {
+; CHECK-LABEL: @test1(
+; CHECK-NEXT: E:
+; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 0
+; CHECK-NEXT: br i1 [[C]], label [[B:%.*]], label [[F:%.*]]
+; CHECK: B:
+; CHECK-NEXT: call void @f2()
+; CHECK-NEXT: ret i32 345
+; CHECK: F:
+; CHECK-NEXT: call void @f3()
+; CHECK-NEXT: ret i32 123
+;
E:
- %C = icmp eq i32 %X, 0 ; <i1> [#uses=2]
- br i1 %C, label %T, label %F
+ %C = icmp eq i32 %X, 0 ; <i1> [#uses=2]
+ br i1 %C, label %T, label %F
T: ; preds = %A, %E
- br i1 %C, label %B, label %A
+ br i1 %C, label %B, label %A
A: ; preds = %T
- call void @f1( )
- br i1 %D, label %T, label %F
+ call void @f1( )
+ br i1 %D, label %T, label %F
B: ; preds = %T
- call void @f2( )
- ret i32 345
+ call void @f2( )
+ ret i32 345
F: ; preds = %A, %E
- call void @f3( )
- ret i32 123
+ call void @f3( )
+ ret i32 123
}
define i32 @test2(i32 %X, i1 %D) {
+; CHECK-LABEL: @test2(
+; CHECK-NEXT: E:
+; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 0
+; CHECK-NEXT: br i1 [[C]], label [[B:%.*]], label [[F:%.*]]
+; CHECK: B:
+; CHECK-NEXT: call void @f2()
+; CHECK-NEXT: ret i32 345
+; CHECK: F:
+; CHECK-NEXT: call void @f3()
+; CHECK-NEXT: ret i32 123
+;
E:
- %C = icmp eq i32 %X, 0 ; <i1> [#uses=2]
- br i1 %C, label %T, label %F
+ %C = icmp eq i32 %X, 0 ; <i1> [#uses=2]
+ br i1 %C, label %T, label %F
T: ; preds = %A, %E
- %P = phi i1 [ true, %E ], [ %C, %A ] ; <i1> [#uses=1]
- br i1 %P, label %B, label %A
+ %P = phi i1 [ true, %E ], [ %C, %A ] ; <i1> [#uses=1]
+ br i1 %P, label %B, label %A
A: ; preds = %T
- call void @f1( )
- br i1 %D, label %T, label %F
+ call void @f1( )
+ br i1 %D, label %T, label %F
B: ; preds = %T
- call void @f2( )
- ret i32 345
+ call void @f2( )
+ ret i32 345
F: ; preds = %A, %E
- call void @f3( )
- ret i32 123
+ call void @f3( )
+ ret i32 123
}
define i32 @test3(i32 %X, i1 %D, i32* %AP, i32* %BP) {
+; CHECK-LABEL: @test3(
+; CHECK-NEXT: E:
+; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 0
+; CHECK-NEXT: br i1 [[C]], label [[B_CRITEDGE:%.*]], label [[F:%.*]]
+; CHECK: B.critedge:
+; CHECK-NEXT: call void @f3()
+; CHECK-NEXT: [[XX_C:%.*]] = load i32, i32* [[AP:%.*]], align 4
+; CHECK-NEXT: store i32 [[XX_C]], i32* [[BP:%.*]], align 4
+; CHECK-NEXT: call void @f2()
+; CHECK-NEXT: ret i32 345
+; CHECK: F:
+; CHECK-NEXT: call void @f3()
+; CHECK-NEXT: ret i32 123
+;
E:
- %C = icmp eq i32 %X, 0 ; <i1> [#uses=2]
- br i1 %C, label %T, label %F
+ %C = icmp eq i32 %X, 0 ; <i1> [#uses=2]
+ br i1 %C, label %T, label %F
T: ; preds = %A, %E
- call void @f3( )
- %XX = load i32, i32* %AP ; <i32> [#uses=1]
- store i32 %XX, i32* %BP
- br i1 %C, label %B, label %A
+ call void @f3( )
+ %XX = load i32, i32* %AP ; <i32> [#uses=1]
+ store i32 %XX, i32* %BP
+ br i1 %C, label %B, label %A
A: ; preds = %T
- call void @f1( )
- br i1 %D, label %T, label %F
+ call void @f1( )
+ br i1 %D, label %T, label %F
B: ; preds = %T
- call void @f2( )
- ret i32 345
+ call void @f2( )
+ ret i32 345
F: ; preds = %A, %E
- call void @f3( )
- ret i32 123
+ call void @f3( )
+ ret i32 123
}
diff --git a/llvm/test/Transforms/SimplifyCFG/dbginfo.ll b/llvm/test/Transforms/SimplifyCFG/dbginfo.ll
index 6077151a6187..1630f2f48e5c 100644
--- a/llvm/test/Transforms/SimplifyCFG/dbginfo.ll
+++ b/llvm/test/Transforms/SimplifyCFG/dbginfo.ll
@@ -1,49 +1,50 @@
-; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | not grep "br label"
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
- %llvm.dbg.anchor.type = type { i32, i32 }
- %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 }
- %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8* }
- %llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }* }
- %llvm.dbg.derivedtype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }* }
- %llvm.dbg.global_variable.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1, { }* }
- %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 }
- %llvm.dbg.subrange.type = type { i32, i64, i64 }
- %struct.Group = type { %struct.Scene, %struct.Sphere, %"struct.std::list<Scene*,std::allocator<Scene*> >" }
- %struct.Ray = type { %struct.Vec, %struct.Vec }
- %struct.Scene = type { i32 (...)** }
- %struct.Sphere = type { %struct.Scene, %struct.Vec, double }
- %struct.Vec = type { double, double, double }
- %struct.__class_type_info_pseudo = type { %struct.__type_info_pseudo }
- %struct.__false_type = type <{ i8 }>
- %"struct.__gnu_cxx::new_allocator<Scene*>" = type <{ i8 }>
- %"struct.__gnu_cxx::new_allocator<std::_List_node<Scene*> >" = type <{ i8 }>
- %struct.__si_class_type_info_pseudo = type { %struct.__type_info_pseudo, %"struct.std::type_info"* }
- %struct.__type_info_pseudo = type { i8*, i8* }
- %"struct.std::Hit" = type { double, %struct.Vec }
- %"struct.std::_List_base<Scene*,std::allocator<Scene*> >" = type { %"struct.std::_List_base<Scene*,std::allocator<Scene*> >::_List_impl" }
- %"struct.std::_List_base<Scene*,std::allocator<Scene*> >::_List_impl" = type { %"struct.std::_List_node_base" }
- %"struct.std::_List_const_iterator<Scene*>" = type { %"struct.std::_List_node_base"* }
- %"struct.std::_List_iterator<Scene*>" = type { %"struct.std::_List_node_base"* }
- %"struct.std::_List_node<Scene*>" = type { %"struct.std::_List_node_base", %struct.Scene* }
- %"struct.std::_List_node_base" = type { %"struct.std::_List_node_base"*, %"struct.std::_List_node_base"* }
- %"struct.std::allocator<Scene*>" = type <{ i8 }>
- %"struct.std::allocator<std::_List_node<Scene*> >" = type <{ i8 }>
- %"struct.std::basic_ios<char,std::char_traits<char> >" = type { %"struct.std::ios_base", %"struct.std::basic_ostream<char,std::char_traits<char> >"*, i8, i8, %"struct.std::basic_streambuf<char,std::char_traits<char> >"*, %"struct.std::ctype<char>"*, %"struct.std::num_get<char,std::istreambuf_iterator<char, std::char_traits<char> > >"*, %"struct.std::num_get<char,std::istreambuf_iterator<char, std::char_traits<char> > >"* }
- %"struct.std::basic_ostream<char,std::char_traits<char> >" = type { i32 (...)**, %"struct.std::basic_ios<char,std::char_traits<char> >" }
- %"struct.std::basic_streambuf<char,std::char_traits<char> >" = type { i32 (...)**, i8*, i8*, i8*, i8*, i8*, i8*, %"struct.std::locale" }
- %"struct.std::ctype<char>" = type { %"struct.std::locale::facet", i32*, i8, i32*, i32*, i32*, i8, [256 x i8], [256 x i8], i8 }
- %"struct.std::ios_base" = type { i32 (...)**, i32, i32, i32, i32, i32, %"struct.std::ios_base::_Callback_list"*, %"struct.std::ios_base::_Words", [8 x %"struct.std::ios_base::_Words"], i32, %"struct.std::ios_base::_Words"*, %"struct.std::locale" }
- %"struct.std::ios_base::Init" = type <{ i8 }>
- %"struct.std::ios_base::_Callback_list" = type { %"struct.std::ios_base::_Callback_list"*, void (i32, %"struct.std::ios_base"*, i32)*, i32, i32 }
- %"struct.std::ios_base::_Words" = type { i8*, i32 }
- %"struct.std::list<Scene*,std::allocator<Scene*> >" = type { %"struct.std::_List_base<Scene*,std::allocator<Scene*> >" }
- %"struct.std::locale" = type { %"struct.std::locale::_Impl"* }
- %"struct.std::locale::_Impl" = type { i32, %"struct.std::locale::facet"**, i32, %"struct.std::locale::facet"**, i8** }
- %"struct.std::locale::facet" = type { i32 (...)**, i32 }
- %"struct.std::num_get<char,std::istreambuf_iterator<char, std::char_traits<char> > >" = type { %"struct.std::locale::facet" }
- %"struct.std::num_put<char,std::ostreambuf_iterator<char, std::char_traits<char> > >" = type { %"struct.std::locale::facet" }
- %"struct.std::numeric_limits<double>" = type <{ i8 }>
- %"struct.std::type_info" = type { i32 (...)**, i8* }
+ %llvm.dbg.anchor.type = type { i32, i32 }
+ %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 }
+ %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8* }
+ %llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }* }
+ %llvm.dbg.derivedtype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }* }
+ %llvm.dbg.global_variable.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1, { }* }
+ %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 }
+ %llvm.dbg.subrange.type = type { i32, i64, i64 }
+ %struct.Group = type { %struct.Scene, %struct.Sphere, %"struct.std::list<Scene*,std::allocator<Scene*> >" }
+ %struct.Ray = type { %struct.Vec, %struct.Vec }
+ %struct.Scene = type { i32 (...)** }
+ %struct.Sphere = type { %struct.Scene, %struct.Vec, double }
+ %struct.Vec = type { double, double, double }
+ %struct.__class_type_info_pseudo = type { %struct.__type_info_pseudo }
+ %struct.__false_type = type <{ i8 }>
+ %"struct.__gnu_cxx::new_allocator<Scene*>" = type <{ i8 }>
+ %"struct.__gnu_cxx::new_allocator<std::_List_node<Scene*> >" = type <{ i8 }>
+ %struct.__si_class_type_info_pseudo = type { %struct.__type_info_pseudo, %"struct.std::type_info"* }
+ %struct.__type_info_pseudo = type { i8*, i8* }
+ %"struct.std::Hit" = type { double, %struct.Vec }
+ %"struct.std::_List_base<Scene*,std::allocator<Scene*> >" = type { %"struct.std::_List_base<Scene*,std::allocator<Scene*> >::_List_impl" }
+ %"struct.std::_List_base<Scene*,std::allocator<Scene*> >::_List_impl" = type { %"struct.std::_List_node_base" }
+ %"struct.std::_List_const_iterator<Scene*>" = type { %"struct.std::_List_node_base"* }
+ %"struct.std::_List_iterator<Scene*>" = type { %"struct.std::_List_node_base"* }
+ %"struct.std::_List_node<Scene*>" = type { %"struct.std::_List_node_base", %struct.Scene* }
+ %"struct.std::_List_node_base" = type { %"struct.std::_List_node_base"*, %"struct.std::_List_node_base"* }
+ %"struct.std::allocator<Scene*>" = type <{ i8 }>
+ %"struct.std::allocator<std::_List_node<Scene*> >" = type <{ i8 }>
+ %"struct.std::basic_ios<char,std::char_traits<char> >" = type { %"struct.std::ios_base", %"struct.std::basic_ostream<char,std::char_traits<char> >"*, i8, i8, %"struct.std::basic_streambuf<char,std::char_traits<char> >"*, %"struct.std::ctype<char>"*, %"struct.std::num_get<char,std::istreambuf_iterator<char, std::char_traits<char> > >"*, %"struct.std::num_get<char,std::istreambuf_iterator<char, std::char_traits<char> > >"* }
+ %"struct.std::basic_ostream<char,std::char_traits<char> >" = type { i32 (...)**, %"struct.std::basic_ios<char,std::char_traits<char> >" }
+ %"struct.std::basic_streambuf<char,std::char_traits<char> >" = type { i32 (...)**, i8*, i8*, i8*, i8*, i8*, i8*, %"struct.std::locale" }
+ %"struct.std::ctype<char>" = type { %"struct.std::locale::facet", i32*, i8, i32*, i32*, i32*, i8, [256 x i8], [256 x i8], i8 }
+ %"struct.std::ios_base" = type { i32 (...)**, i32, i32, i32, i32, i32, %"struct.std::ios_base::_Callback_list"*, %"struct.std::ios_base::_Words", [8 x %"struct.std::ios_base::_Words"], i32, %"struct.std::ios_base::_Words"*, %"struct.std::locale" }
+ %"struct.std::ios_base::Init" = type <{ i8 }>
+ %"struct.std::ios_base::_Callback_list" = type { %"struct.std::ios_base::_Callback_list"*, void (i32, %"struct.std::ios_base"*, i32)*, i32, i32 }
+ %"struct.std::ios_base::_Words" = type { i8*, i32 }
+ %"struct.std::list<Scene*,std::allocator<Scene*> >" = type { %"struct.std::_List_base<Scene*,std::allocator<Scene*> >" }
+ %"struct.std::locale" = type { %"struct.std::locale::_Impl"* }
+ %"struct.std::locale::_Impl" = type { i32, %"struct.std::locale::facet"**, i32, %"struct.std::locale::facet"**, i8** }
+ %"struct.std::locale::facet" = type { i32 (...)**, i32 }
+ %"struct.std::num_get<char,std::istreambuf_iterator<char, std::char_traits<char> > >" = type { %"struct.std::locale::facet" }
+ %"struct.std::num_put<char,std::ostreambuf_iterator<char, std::char_traits<char> > >" = type { %"struct.std::locale::facet" }
+ %"struct.std::numeric_limits<double>" = type <{ i8 }>
+ %"struct.std::type_info" = type { i32 (...)**, i8* }
@llvm.dbg.subprogram947 = external constant %llvm.dbg.subprogram.type ; <%llvm.dbg.subprogram.type*> [#uses=1]
declare void @llvm.dbg.func.start({ }*) nounwind
@@ -53,19 +54,30 @@ declare void @llvm.dbg.region.end({ }*) nounwind
declare void @_ZN9__gnu_cxx13new_allocatorIP5SceneED2Ev(%struct.__false_type*) nounwind
define void @_ZNSaIP5SceneED1Ev(%struct.__false_type* %this) nounwind {
+; CHECK-LABEL: @_ZNSaIP5SceneED1Ev(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.__false_type*, align 8
+; CHECK-NEXT: %"alloca point" = bitcast i32 0 to i32
+; CHECK-NEXT: call void @llvm.dbg.func.start({}* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram947 to {}*))
+; CHECK-NEXT: store %struct.__false_type* [[THIS:%.*]], %struct.__false_type** [[THIS_ADDR]], align 8
+; CHECK-NEXT: [[TMP0:%.*]] = load %struct.__false_type*, %struct.__false_type** [[THIS_ADDR]], align 4
+; CHECK-NEXT: call void @_ZN9__gnu_cxx13new_allocatorIP5SceneED2Ev(%struct.__false_type* [[TMP0]]) #[[ATTR0:[0-9]+]]
+; CHECK-NEXT: call void @llvm.dbg.region.end({}* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram947 to {}*))
+; CHECK-NEXT: ret void
+;
entry:
- %this_addr = alloca %struct.__false_type* ; <%struct.__false_type**> [#uses=2]
- %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
- call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram947 to { }*))
- store %struct.__false_type* %this, %struct.__false_type** %this_addr
- %0 = load %struct.__false_type*, %struct.__false_type** %this_addr, align 4 ; <%struct.__false_type*> [#uses=1]
- call void @_ZN9__gnu_cxx13new_allocatorIP5SceneED2Ev(%struct.__false_type* %0) nounwind
- br label %bb
+ %this_addr = alloca %struct.__false_type* ; <%struct.__false_type**> [#uses=2]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram947 to { }*))
+ store %struct.__false_type* %this, %struct.__false_type** %this_addr
+ %0 = load %struct.__false_type*, %struct.__false_type** %this_addr, align 4 ; <%struct.__false_type*> [#uses=1]
+ call void @_ZN9__gnu_cxx13new_allocatorIP5SceneED2Ev(%struct.__false_type* %0) nounwind
+ br label %bb
bb: ; preds = %entry
- br label %return
+ br label %return
return: ; preds = %bb
- call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram947 to { }*))
- ret void
+ call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram947 to { }*))
+ ret void
}
diff --git a/llvm/test/Transforms/SimplifyCFG/duplicate-phis.ll b/llvm/test/Transforms/SimplifyCFG/duplicate-phis.ll
index d3b76fd3ea05..16d639b6e80f 100644
--- a/llvm/test/Transforms/SimplifyCFG/duplicate-phis.ll
+++ b/llvm/test/Transforms/SimplifyCFG/duplicate-phis.ll
@@ -1,9 +1,22 @@
-; RUN: opt < %s -instcombine -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | grep " = phi " | count 1
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -instcombine -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
; instcombine should sort the PHI operands so that simplifycfg can see the
; duplicate and remove it.
define i32 @foo(i1 %t) {
+; CHECK-LABEL: @foo(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: call void @bar()
+; CHECK-NEXT: br i1 [[T:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
+; CHECK: true:
+; CHECK-NEXT: call void @bar()
+; CHECK-NEXT: br label [[FALSE]]
+; CHECK: false:
+; CHECK-NEXT: [[A:%.*]] = phi i32 [ 4, [[TRUE]] ], [ 10, [[ENTRY:%.*]] ]
+; CHECK-NEXT: call void @bar()
+; CHECK-NEXT: ret i32 [[A]]
+;
entry:
call void @bar()
br i1 %t, label %true, label %false
diff --git a/llvm/test/Transforms/SimplifyCFG/hoist-common-code.ll b/llvm/test/Transforms/SimplifyCFG/hoist-common-code.ll
index 2b43b511432e..4138a4ab982a 100644
--- a/llvm/test/Transforms/SimplifyCFG/hoist-common-code.ll
+++ b/llvm/test/Transforms/SimplifyCFG/hoist-common-code.ll
@@ -1,18 +1,25 @@
-; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S -hoist-common-insts=true | not grep br
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S -hoist-common-insts=true | FileCheck %s
declare void @bar(i32)
define void @test(i1 %P, i32* %Q) {
- br i1 %P, label %T, label %F
+; CHECK-LABEL: @test(
+; CHECK-NEXT: store i32 1, i32* [[Q:%.*]], align 4
+; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[Q]], align 4
+; CHECK-NEXT: call void @bar(i32 [[A]])
+; CHECK-NEXT: ret void
+;
+ br i1 %P, label %T, label %F
T: ; preds = %0
- store i32 1, i32* %Q
- %A = load i32, i32* %Q ; <i32> [#uses=1]
- call void @bar( i32 %A )
- ret void
+ store i32 1, i32* %Q
+ %A = load i32, i32* %Q ; <i32> [#uses=1]
+ call void @bar( i32 %A )
+ ret void
F: ; preds = %0
- store i32 1, i32* %Q
- %B = load i32, i32* %Q ; <i32> [#uses=1]
- call void @bar( i32 %B )
- ret void
+ store i32 1, i32* %Q
+ %B = load i32, i32* %Q ; <i32> [#uses=1]
+ call void @bar( i32 %B )
+ ret void
}
diff --git a/llvm/test/Transforms/SimplifyCFG/iterative-simplify.ll b/llvm/test/Transforms/SimplifyCFG/iterative-simplify.ll
index ef2482134e7d..63fd9f9787eb 100644
--- a/llvm/test/Transforms/SimplifyCFG/iterative-simplify.ll
+++ b/llvm/test/Transforms/SimplifyCFG/iterative-simplify.ll
@@ -1,98 +1,140 @@
-; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | not grep bb17
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
; PR1786
define i32 @main() {
+; CHECK-LABEL: @main(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[Z:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[Z16:%.*]] = alloca i32, align 4
+; CHECK-NEXT: %"alloca point" = bitcast i32 0 to i32
+; CHECK-NEXT: store i32 0, i32* [[I]], align 4
+; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8 1, 0
+; CHECK-NEXT: br i1 [[TOBOOL]], label [[COND_TRUE:%.*]], label [[COND_FALSE33:%.*]]
+; CHECK: cond_true:
+; CHECK-NEXT: store i32 0, i32* [[Z]], align 4
+; CHECK-NEXT: br label [[BB:%.*]]
+; CHECK: bb:
+; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[Z]], align 4
+; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[TMP]], 16384
+; CHECK-NEXT: store i32 [[TMP1]], i32* [[Z]], align 4
+; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[I]], align 4
+; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[TMP2]], 1
+; CHECK-NEXT: store i32 [[TMP3]], i32* [[I]], align 4
+; CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* [[I]], align 4
+; CHECK-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[TMP4]], 262144
+; CHECK-NEXT: [[TMP56:%.*]] = zext i1 [[TMP5]] to i8
+; CHECK-NEXT: [[TOBOOL7:%.*]] = icmp ne i8 [[TMP56]], 0
+; CHECK-NEXT: br i1 [[TOBOOL7]], label [[COND_TRUE8:%.*]], label [[COND_NEXT:%.*]]
+; CHECK: cond_true8:
+; CHECK-NEXT: call void @abort()
+; CHECK-NEXT: unreachable
+; CHECK: cond_next:
+; CHECK-NEXT: [[TMP9:%.*]] = load i32, i32* [[Z]], align 4
+; CHECK-NEXT: [[TMP10:%.*]] = icmp ne i32 [[TMP9]], 0
+; CHECK-NEXT: [[TMP1011:%.*]] = zext i1 [[TMP10]] to i8
+; CHECK-NEXT: [[TOBOOL12:%.*]] = icmp ne i8 [[TMP1011]], 0
+; CHECK-NEXT: br i1 [[TOBOOL12]], label [[BB]], label [[BB13:%.*]]
+; CHECK: bb13:
+; CHECK-NEXT: call void @exit(i32 0)
+; CHECK-NEXT: unreachable
+; CHECK: cond_false33:
+; CHECK-NEXT: call void @exit(i32 0)
+; CHECK-NEXT: unreachable
+;
entry:
- %retval = alloca i32, align 4 ; <i32*> [#uses=1]
- %i = alloca i32, align 4 ; <i32*> [#uses=7]
- %z = alloca i32, align 4 ; <i32*> [#uses=4]
- %z16 = alloca i32, align 4 ; <i32*> [#uses=4]
- %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
- store i32 0, i32* %i
- %toBool = icmp ne i8 1, 0 ; <i1> [#uses=1]
- br i1 %toBool, label %cond_true, label %cond_false
+ %retval = alloca i32, align 4 ; <i32*> [#uses=1]
+ %i = alloca i32, align 4 ; <i32*> [#uses=7]
+ %z = alloca i32, align 4 ; <i32*> [#uses=4]
+ %z16 = alloca i32, align 4 ; <i32*> [#uses=4]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ store i32 0, i32* %i
+ %toBool = icmp ne i8 1, 0 ; <i1> [#uses=1]
+ br i1 %toBool, label %cond_true, label %cond_false
cond_true: ; preds = %entry
- store i32 0, i32* %z
- br label %bb
+ store i32 0, i32* %z
+ br label %bb
bb: ; preds = %cond_next, %cond_true
- %tmp = load i32, i32* %z ; <i32> [#uses=1]
- %tmp1 = sub i32 %tmp, 16384 ; <i32> [#uses=1]
- store i32 %tmp1, i32* %z
- %tmp2 = load i32, i32* %i ; <i32> [#uses=1]
- %tmp3 = add i32 %tmp2, 1 ; <i32> [#uses=1]
- store i32 %tmp3, i32* %i
- %tmp4 = load i32, i32* %i ; <i32> [#uses=1]
- %tmp5 = icmp sgt i32 %tmp4, 262144 ; <i1> [#uses=1]
- %tmp56 = zext i1 %tmp5 to i8 ; <i8> [#uses=1]
- %toBool7 = icmp ne i8 %tmp56, 0 ; <i1> [#uses=1]
- br i1 %toBool7, label %cond_true8, label %cond_next
+ %tmp = load i32, i32* %z ; <i32> [#uses=1]
+ %tmp1 = sub i32 %tmp, 16384 ; <i32> [#uses=1]
+ store i32 %tmp1, i32* %z
+ %tmp2 = load i32, i32* %i ; <i32> [#uses=1]
+ %tmp3 = add i32 %tmp2, 1 ; <i32> [#uses=1]
+ store i32 %tmp3, i32* %i
+ %tmp4 = load i32, i32* %i ; <i32> [#uses=1]
+ %tmp5 = icmp sgt i32 %tmp4, 262144 ; <i1> [#uses=1]
+ %tmp56 = zext i1 %tmp5 to i8 ; <i8> [#uses=1]
+ %toBool7 = icmp ne i8 %tmp56, 0 ; <i1> [#uses=1]
+ br i1 %toBool7, label %cond_true8, label %cond_next
cond_true8: ; preds = %bb
- call void @abort( )
- unreachable
+ call void @abort( )
+ unreachable
cond_next: ; preds = %bb
- %tmp9 = load i32, i32* %z ; <i32> [#uses=1]
- %tmp10 = icmp ne i32 %tmp9, 0 ; <i1> [#uses=1]
- %tmp1011 = zext i1 %tmp10 to i8 ; <i8> [#uses=1]
- %toBool12 = icmp ne i8 %tmp1011, 0 ; <i1> [#uses=1]
- br i1 %toBool12, label %bb, label %bb13
+ %tmp9 = load i32, i32* %z ; <i32> [#uses=1]
+ %tmp10 = icmp ne i32 %tmp9, 0 ; <i1> [#uses=1]
+ %tmp1011 = zext i1 %tmp10 to i8 ; <i8> [#uses=1]
+ %toBool12 = icmp ne i8 %tmp1011, 0 ; <i1> [#uses=1]
+ br i1 %toBool12, label %bb, label %bb13
bb13: ; preds = %cond_next
- call void @exit( i32 0 )
- unreachable
+ call void @exit( i32 0 )
+ unreachable
cond_false: ; preds = %entry
- %toBool14 = icmp ne i8 1, 0 ; <i1> [#uses=1]
- br i1 %toBool14, label %cond_true15, label %cond_false33
+ %toBool14 = icmp ne i8 1, 0 ; <i1> [#uses=1]
+ br i1 %toBool14, label %cond_true15, label %cond_false33
cond_true15: ; preds = %cond_false
- store i32 0, i32* %z16
- br label %bb17
+ store i32 0, i32* %z16
+ br label %bb17
bb17: ; preds = %cond_next27, %cond_true15
- %tmp18 = load i32, i32* %z16 ; <i32> [#uses=1]
- %tmp19 = sub i32 %tmp18, 16384 ; <i32> [#uses=1]
- store i32 %tmp19, i32* %z16
- %tmp20 = load i32, i32* %i ; <i32> [#uses=1]
- %tmp21 = add i32 %tmp20, 1 ; <i32> [#uses=1]
- store i32 %tmp21, i32* %i
- %tmp22 = load i32, i32* %i ; <i32> [#uses=1]
- %tmp23 = icmp sgt i32 %tmp22, 262144 ; <i1> [#uses=1]
- %tmp2324 = zext i1 %tmp23 to i8 ; <i8> [#uses=1]
- %toBool25 = icmp ne i8 %tmp2324, 0 ; <i1> [#uses=1]
- br i1 %toBool25, label %cond_true26, label %cond_next27
+ %tmp18 = load i32, i32* %z16 ; <i32> [#uses=1]
+ %tmp19 = sub i32 %tmp18, 16384 ; <i32> [#uses=1]
+ store i32 %tmp19, i32* %z16
+ %tmp20 = load i32, i32* %i ; <i32> [#uses=1]
+ %tmp21 = add i32 %tmp20, 1 ; <i32> [#uses=1]
+ store i32 %tmp21, i32* %i
+ %tmp22 = load i32, i32* %i ; <i32> [#uses=1]
+ %tmp23 = icmp sgt i32 %tmp22, 262144 ; <i1> [#uses=1]
+ %tmp2324 = zext i1 %tmp23 to i8 ; <i8> [#uses=1]
+ %toBool25 = icmp ne i8 %tmp2324, 0 ; <i1> [#uses=1]
+ br i1 %toBool25, label %cond_true26, label %cond_next27
cond_true26: ; preds = %bb17
- call void @abort( )
- unreachable
+ call void @abort( )
+ unreachable
cond_next27: ; preds = %bb17
- %tmp28 = load i32, i32* %z16 ; <i32> [#uses=1]
- %tmp29 = icmp ne i32 %tmp28, 0 ; <i1> [#uses=1]
- %tmp2930 = zext i1 %tmp29 to i8 ; <i8> [#uses=1]
- %toBool31 = icmp ne i8 %tmp2930, 0 ; <i1> [#uses=1]
- br i1 %toBool31, label %bb17, label %bb32
+ %tmp28 = load i32, i32* %z16 ; <i32> [#uses=1]
+ %tmp29 = icmp ne i32 %tmp28, 0 ; <i1> [#uses=1]
+ %tmp2930 = zext i1 %tmp29 to i8 ; <i8> [#uses=1]
+ %toBool31 = icmp ne i8 %tmp2930, 0 ; <i1> [#uses=1]
+ br i1 %toBool31, label %bb17, label %bb32
bb32: ; preds = %cond_next27
- call void @exit( i32 0 )
- unreachable
+ call void @exit( i32 0 )
+ unreachable
cond_false33: ; preds = %cond_false
- call void @exit( i32 0 )
- unreachable
+ call void @exit( i32 0 )
+ unreachable
cond_next34: ; No predecessors!
- br label %cond_next35
+ br label %cond_next35
cond_next35: ; preds = %cond_next34
- br label %return
+ br label %return
return: ; preds = %cond_next35
- %retval36 = load i32, i32* %retval ; <i32> [#uses=1]
- ret i32 %retval36
+ %retval36 = load i32, i32* %retval ; <i32> [#uses=1]
+ ret i32 %retval36
}
declare void @abort()
diff --git a/llvm/test/Transforms/SimplifyCFG/return-merge.ll b/llvm/test/Transforms/SimplifyCFG/return-merge.ll
index f65cf4925e6e..31df0bf8059f 100644
--- a/llvm/test/Transforms/SimplifyCFG/return-merge.ll
+++ b/llvm/test/Transforms/SimplifyCFG/return-merge.ll
@@ -1,19 +1,29 @@
-; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | not grep br
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
define i32 @test1(i1 %C) {
+; CHECK-LABEL: @test1(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[C:%.*]], i32 1, i32 0
+; CHECK-NEXT: ret i32 [[SPEC_SELECT]]
+;
entry:
- br i1 %C, label %T, label %F
+ br i1 %C, label %T, label %F
T: ; preds = %entry
- ret i32 1
+ ret i32 1
F: ; preds = %entry
- ret i32 0
+ ret i32 0
}
define void @test2(i1 %C) {
- br i1 %C, label %T, label %F
+; CHECK-LABEL: @test2(
+; CHECK-NEXT: T:
+; CHECK-NEXT: ret void
+;
+ br i1 %C, label %T, label %F
T: ; preds = %0
- ret void
+ ret void
F: ; preds = %0
- ret void
+ ret void
}
More information about the llvm-commits
mailing list