Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
; RUN: llc -enable-machine-outliner -mtriple=sparc-unknown-linux < %s | FileCheck %s
;
; NOTE: Machine outliner doesn't run.
@x = global i32 0, align 4

define i32 @check_boundaries() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4
store i32 0, i32* %1, align 4
store i32 0, i32* %2, align 4
%6 = load i32, i32* %2, align 4
%7 = icmp ne i32 %6, 0
br i1 %7, label %9, label %8

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %10

store i32 1, i32* %4, align 4
br label %10

%11 = load i32, i32* %2, align 4
%12 = icmp ne i32 %11, 0
br i1 %12, label %14, label %13

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %15

store i32 1, i32* %4, align 4
br label %15

ret i32 0
}

define i32 @main() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4

store i32 0, i32* %1, align 4
store i32 0, i32* @x, align 4
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
store i32 1, i32* @x, align 4
call void asm sideeffect "", "~{memory},~{dirflag},~{fpsr},~{flags}"()
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
ret i32 0
}

attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --include-generated-funcs
; RUN: llc -enable-machine-outliner -mtriple=sparc-unknown-linux < %s | FileCheck %s
; NOTE: Machine outliner doesn't run.
@x = global i32 0, align 4

define i32 @check_boundaries() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4
store i32 0, i32* %1, align 4
store i32 0, i32* %2, align 4
%6 = load i32, i32* %2, align 4
%7 = icmp ne i32 %6, 0
br i1 %7, label %9, label %8

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %10

store i32 1, i32* %4, align 4
br label %10

%11 = load i32, i32* %2, align 4
%12 = icmp ne i32 %11, 0
br i1 %12, label %14, label %13

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %15

store i32 1, i32* %4, align 4
br label %15

ret i32 0
}

define i32 @main() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4

store i32 0, i32* %1, align 4
store i32 0, i32* @x, align 4
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
store i32 1, i32* @x, align 4
call void asm sideeffect "", "~{memory},~{dirflag},~{fpsr},~{flags}"()
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
ret i32 0
}

attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
; CHECK-LABEL: check_boundaries:
; CHECK: .cfi_startproc
; CHECK-NEXT: ! %bb.0:
; CHECK-NEXT: save %sp, -112, %sp
; CHECK-NEXT: .cfi_def_cfa_register %fp
; CHECK-NEXT: .cfi_window_save
; CHECK-NEXT: .cfi_register %o7, %i7
; CHECK-NEXT: st %g0, [%fp+-4]
; CHECK-NEXT: mov %g0, %i0
; CHECK-NEXT: cmp %i0, 0
; CHECK-NEXT: st %g0, [%fp+-8]
; CHECK-NEXT: be .LBB0_1
; CHECK-NEXT: mov 1, %i0
; CHECK-NEXT: ! %bb.2:
; CHECK-NEXT: ba .LBB0_3
; CHECK-NEXT: st %i0, [%fp+-16]
; CHECK-NEXT: .LBB0_1:
; CHECK-NEXT: st %i0, [%fp+-8]
; CHECK-NEXT: mov 2, %i0
; CHECK-NEXT: st %i0, [%fp+-12]
; CHECK-NEXT: mov 3, %i0
; CHECK-NEXT: st %i0, [%fp+-16]
; CHECK-NEXT: mov 4, %i0
; CHECK-NEXT: st %i0, [%fp+-20]
; CHECK-NEXT: .LBB0_3:
; CHECK-NEXT: ld [%fp+-8], %i0
; CHECK-NEXT: cmp %i0, 0
; CHECK-NEXT: be .LBB0_4
; CHECK-NEXT: nop
; CHECK-NEXT: ! %bb.5:
; CHECK-NEXT: mov 1, %i0
; CHECK-NEXT: ba .LBB0_6
; CHECK-NEXT: st %i0, [%fp+-16]
; CHECK-NEXT: .LBB0_4:
; CHECK-NEXT: mov 1, %i0
; CHECK-NEXT: st %i0, [%fp+-8]
; CHECK-NEXT: mov 2, %i0
; CHECK-NEXT: st %i0, [%fp+-12]
; CHECK-NEXT: mov 3, %i0
; CHECK-NEXT: st %i0, [%fp+-16]
; CHECK-NEXT: mov 4, %i0
; CHECK-NEXT: st %i0, [%fp+-20]
; CHECK-NEXT: .LBB0_6:
; CHECK-NEXT: ret
; CHECK-NEXT: restore %g0, %g0, %o0
;
; CHECK-LABEL: main:
; CHECK: .cfi_startproc
; CHECK-NEXT: ! %bb.0:
; CHECK-NEXT: save %sp, -112, %sp
; CHECK-NEXT: .cfi_def_cfa_register %fp
; CHECK-NEXT: .cfi_window_save
; CHECK-NEXT: .cfi_register %o7, %i7
; CHECK-NEXT: st %g0, [%fp+-4]
; CHECK-NEXT: sethi %hi(x), %i0
; CHECK-NEXT: mov 1, %i1
; CHECK-NEXT: st %i1, [%fp+-8]
; CHECK-NEXT: mov 2, %i2
; CHECK-NEXT: st %i2, [%fp+-12]
; CHECK-NEXT: mov 3, %i3
; CHECK-NEXT: st %i3, [%fp+-16]
; CHECK-NEXT: mov 4, %i4
; CHECK-NEXT: st %i4, [%fp+-20]
; CHECK-NEXT: st %i1, [%i0+%lo(x)]
; CHECK-NEXT: !APP
; CHECK-NEXT: !NO_APP
; CHECK-NEXT: st %i1, [%fp+-8]
; CHECK-NEXT: st %i2, [%fp+-12]
; CHECK-NEXT: st %i3, [%fp+-16]
; CHECK-NEXT: mov %g0, %i0
; CHECK-NEXT: st %i4, [%fp+-20]
; CHECK-NEXT: ret
; CHECK-NEXT: restore
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -enable-machine-outliner -mtriple=sparc-unknown-linux < %s | FileCheck %s
;
; NOTE: Machine outliner doesn't run.
@x = global i32 0, align 4

define i32 @check_boundaries() #0 {
; CHECK-LABEL: check_boundaries:
; CHECK: .cfi_startproc
; CHECK-NEXT: ! %bb.0:
; CHECK-NEXT: save %sp, -112, %sp
; CHECK-NEXT: .cfi_def_cfa_register %fp
; CHECK-NEXT: .cfi_window_save
; CHECK-NEXT: .cfi_register %o7, %i7
; CHECK-NEXT: st %g0, [%fp+-4]
; CHECK-NEXT: mov %g0, %i0
; CHECK-NEXT: cmp %i0, 0
; CHECK-NEXT: st %g0, [%fp+-8]
; CHECK-NEXT: be .LBB0_1
; CHECK-NEXT: mov 1, %i0
; CHECK-NEXT: ! %bb.2:
; CHECK-NEXT: ba .LBB0_3
; CHECK-NEXT: st %i0, [%fp+-16]
; CHECK-NEXT: .LBB0_1:
; CHECK-NEXT: st %i0, [%fp+-8]
; CHECK-NEXT: mov 2, %i0
; CHECK-NEXT: st %i0, [%fp+-12]
; CHECK-NEXT: mov 3, %i0
; CHECK-NEXT: st %i0, [%fp+-16]
; CHECK-NEXT: mov 4, %i0
; CHECK-NEXT: st %i0, [%fp+-20]
; CHECK-NEXT: .LBB0_3:
; CHECK-NEXT: ld [%fp+-8], %i0
; CHECK-NEXT: cmp %i0, 0
; CHECK-NEXT: be .LBB0_4
; CHECK-NEXT: nop
; CHECK-NEXT: ! %bb.5:
; CHECK-NEXT: mov 1, %i0
; CHECK-NEXT: ba .LBB0_6
; CHECK-NEXT: st %i0, [%fp+-16]
; CHECK-NEXT: .LBB0_4:
; CHECK-NEXT: mov 1, %i0
; CHECK-NEXT: st %i0, [%fp+-8]
; CHECK-NEXT: mov 2, %i0
; CHECK-NEXT: st %i0, [%fp+-12]
; CHECK-NEXT: mov 3, %i0
; CHECK-NEXT: st %i0, [%fp+-16]
; CHECK-NEXT: mov 4, %i0
; CHECK-NEXT: st %i0, [%fp+-20]
; CHECK-NEXT: .LBB0_6:
; CHECK-NEXT: ret
; CHECK-NEXT: restore %g0, %g0, %o0
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4
store i32 0, i32* %1, align 4
store i32 0, i32* %2, align 4
%6 = load i32, i32* %2, align 4
%7 = icmp ne i32 %6, 0
br i1 %7, label %9, label %8

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %10

store i32 1, i32* %4, align 4
br label %10

%11 = load i32, i32* %2, align 4
%12 = icmp ne i32 %11, 0
br i1 %12, label %14, label %13

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %15

store i32 1, i32* %4, align 4
br label %15

ret i32 0
}

define i32 @main() #0 {
; CHECK-LABEL: main:
; CHECK: .cfi_startproc
; CHECK-NEXT: ! %bb.0:
; CHECK-NEXT: save %sp, -112, %sp
; CHECK-NEXT: .cfi_def_cfa_register %fp
; CHECK-NEXT: .cfi_window_save
; CHECK-NEXT: .cfi_register %o7, %i7
; CHECK-NEXT: st %g0, [%fp+-4]
; CHECK-NEXT: sethi %hi(x), %i0
; CHECK-NEXT: mov 1, %i1
; CHECK-NEXT: st %i1, [%fp+-8]
; CHECK-NEXT: mov 2, %i2
; CHECK-NEXT: st %i2, [%fp+-12]
; CHECK-NEXT: mov 3, %i3
; CHECK-NEXT: st %i3, [%fp+-16]
; CHECK-NEXT: mov 4, %i4
; CHECK-NEXT: st %i4, [%fp+-20]
; CHECK-NEXT: st %i1, [%i0+%lo(x)]
; CHECK-NEXT: !APP
; CHECK-NEXT: !NO_APP
; CHECK-NEXT: st %i1, [%fp+-8]
; CHECK-NEXT: st %i2, [%fp+-12]
; CHECK-NEXT: st %i3, [%fp+-16]
; CHECK-NEXT: mov %g0, %i0
; CHECK-NEXT: st %i4, [%fp+-20]
; CHECK-NEXT: ret
; CHECK-NEXT: restore
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4

store i32 0, i32* %1, align 4
store i32 0, i32* @x, align 4
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
store i32 1, i32* @x, align 4
call void asm sideeffect "", "~{memory},~{dirflag},~{fpsr},~{flags}"()
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
ret i32 0
}

attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
; RUN: llc -enable-machine-outliner -mtriple=s390x-unknown-linux < %s | FileCheck %s
;
; NOTE: Machine outliner doesn't run.
@x = global i32 0, align 4

define i32 @check_boundaries() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4
store i32 0, i32* %1, align 4
store i32 0, i32* %2, align 4
%6 = load i32, i32* %2, align 4
%7 = icmp ne i32 %6, 0
br i1 %7, label %9, label %8

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %10

store i32 1, i32* %4, align 4
br label %10

%11 = load i32, i32* %2, align 4
%12 = icmp ne i32 %11, 0
br i1 %12, label %14, label %13

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %15

store i32 1, i32* %4, align 4
br label %15

ret i32 0
}

define i32 @main() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4

store i32 0, i32* %1, align 4
store i32 0, i32* @x, align 4
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
store i32 1, i32* @x, align 4
call void asm sideeffect "", "~{memory},~{dirflag},~{fpsr},~{flags}"()
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
ret i32 0
}

attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --include-generated-funcs
; RUN: llc -enable-machine-outliner -mtriple=s390x-unknown-linux < %s | FileCheck %s
; NOTE: Machine outliner doesn't run.
@x = global i32 0, align 4

define i32 @check_boundaries() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4
store i32 0, i32* %1, align 4
store i32 0, i32* %2, align 4
%6 = load i32, i32* %2, align 4
%7 = icmp ne i32 %6, 0
br i1 %7, label %9, label %8

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %10

store i32 1, i32* %4, align 4
br label %10

%11 = load i32, i32* %2, align 4
%12 = icmp ne i32 %11, 0
br i1 %12, label %14, label %13

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %15

store i32 1, i32* %4, align 4
br label %15

ret i32 0
}

define i32 @main() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4

store i32 0, i32* %1, align 4
store i32 0, i32* @x, align 4
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
store i32 1, i32* @x, align 4
call void asm sideeffect "", "~{memory},~{dirflag},~{fpsr},~{flags}"()
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
ret i32 0
}

attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
; CHECK-LABEL: check_boundaries:
; CHECK: # %bb.0:
; CHECK-NEXT: stmg %r11, %r15, 88(%r15)
; CHECK-NEXT: .cfi_offset %r11, -72
; CHECK-NEXT: .cfi_offset %r15, -40
; CHECK-NEXT: aghi %r15, -184
; CHECK-NEXT: .cfi_def_cfa_offset 344
; CHECK-NEXT: lgr %r11, %r15
; CHECK-NEXT: .cfi_def_cfa_register %r11
; CHECK-NEXT: mvhi 180(%r11), 0
; CHECK-NEXT: lhi %r0, 0
; CHECK-NEXT: mvhi 176(%r11), 0
; CHECK-NEXT: cije %r0, 0, .LBB0_3
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: mvhi 168(%r11), 1
; CHECK-NEXT: chsi 176(%r11), 0
; CHECK-NEXT: je .LBB0_4
; CHECK-NEXT: .LBB0_2:
; CHECK-NEXT: mvhi 168(%r11), 1
; CHECK-NEXT: j .LBB0_5
; CHECK-NEXT: .LBB0_3:
; CHECK-NEXT: mvhi 176(%r11), 1
; CHECK-NEXT: mvhi 172(%r11), 2
; CHECK-NEXT: mvhi 168(%r11), 3
; CHECK-NEXT: mvhi 164(%r11), 4
; CHECK-NEXT: chsi 176(%r11), 0
; CHECK-NEXT: jlh .LBB0_2
; CHECK-NEXT: .LBB0_4:
; CHECK-NEXT: mvhi 176(%r11), 1
; CHECK-NEXT: mvhi 172(%r11), 2
; CHECK-NEXT: mvhi 168(%r11), 3
; CHECK-NEXT: mvhi 164(%r11), 4
; CHECK-NEXT: .LBB0_5:
; CHECK-NEXT: lhi %r2, 0
; CHECK-NEXT: lmg %r11, %r15, 272(%r11)
; CHECK-NEXT: br %r14
;
; CHECK-LABEL: main:
; CHECK: # %bb.0:
; CHECK-NEXT: stmg %r11, %r15, 88(%r15)
; CHECK-NEXT: .cfi_offset %r11, -72
; CHECK-NEXT: .cfi_offset %r15, -40
; CHECK-NEXT: aghi %r15, -184
; CHECK-NEXT: .cfi_def_cfa_offset 344
; CHECK-NEXT: lgr %r11, %r15
; CHECK-NEXT: .cfi_def_cfa_register %r11
; CHECK-NEXT: mvhi 180(%r11), 0
; CHECK-NEXT: mvhi 176(%r11), 1
; CHECK-NEXT: mvhi 172(%r11), 2
; CHECK-NEXT: mvhi 168(%r11), 3
; CHECK-NEXT: mvhi 164(%r11), 4
; CHECK-NEXT: lhi %r0, 1
; CHECK-NEXT: strl %r0, x
; CHECK-NEXT: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: mvhi 176(%r11), 1
; CHECK-NEXT: mvhi 172(%r11), 2
; CHECK-NEXT: mvhi 168(%r11), 3
; CHECK-NEXT: lhi %r2, 0
; CHECK-NEXT: mvhi 164(%r11), 4
; CHECK-NEXT: lmg %r11, %r15, 272(%r11)
; CHECK-NEXT: br %r14
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -enable-machine-outliner -mtriple=s390x-unknown-linux < %s | FileCheck %s
;
; NOTE: Machine outliner doesn't run.
@x = global i32 0, align 4

define i32 @check_boundaries() #0 {
; CHECK-LABEL: check_boundaries:
; CHECK: # %bb.0:
; CHECK-NEXT: stmg %r11, %r15, 88(%r15)
; CHECK-NEXT: .cfi_offset %r11, -72
; CHECK-NEXT: .cfi_offset %r15, -40
; CHECK-NEXT: aghi %r15, -184
; CHECK-NEXT: .cfi_def_cfa_offset 344
; CHECK-NEXT: lgr %r11, %r15
; CHECK-NEXT: .cfi_def_cfa_register %r11
; CHECK-NEXT: mvhi 180(%r11), 0
; CHECK-NEXT: lhi %r0, 0
; CHECK-NEXT: mvhi 176(%r11), 0
; CHECK-NEXT: cije %r0, 0, .LBB0_3
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: mvhi 168(%r11), 1
; CHECK-NEXT: chsi 176(%r11), 0
; CHECK-NEXT: je .LBB0_4
; CHECK-NEXT: .LBB0_2:
; CHECK-NEXT: mvhi 168(%r11), 1
; CHECK-NEXT: j .LBB0_5
; CHECK-NEXT: .LBB0_3:
; CHECK-NEXT: mvhi 176(%r11), 1
; CHECK-NEXT: mvhi 172(%r11), 2
; CHECK-NEXT: mvhi 168(%r11), 3
; CHECK-NEXT: mvhi 164(%r11), 4
; CHECK-NEXT: chsi 176(%r11), 0
; CHECK-NEXT: jlh .LBB0_2
; CHECK-NEXT: .LBB0_4:
; CHECK-NEXT: mvhi 176(%r11), 1
; CHECK-NEXT: mvhi 172(%r11), 2
; CHECK-NEXT: mvhi 168(%r11), 3
; CHECK-NEXT: mvhi 164(%r11), 4
; CHECK-NEXT: .LBB0_5:
; CHECK-NEXT: lhi %r2, 0
; CHECK-NEXT: lmg %r11, %r15, 272(%r11)
; CHECK-NEXT: br %r14
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4
store i32 0, i32* %1, align 4
store i32 0, i32* %2, align 4
%6 = load i32, i32* %2, align 4
%7 = icmp ne i32 %6, 0
br i1 %7, label %9, label %8

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %10

store i32 1, i32* %4, align 4
br label %10

%11 = load i32, i32* %2, align 4
%12 = icmp ne i32 %11, 0
br i1 %12, label %14, label %13

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %15

store i32 1, i32* %4, align 4
br label %15

ret i32 0
}

define i32 @main() #0 {
; CHECK-LABEL: main:
; CHECK: # %bb.0:
; CHECK-NEXT: stmg %r11, %r15, 88(%r15)
; CHECK-NEXT: .cfi_offset %r11, -72
; CHECK-NEXT: .cfi_offset %r15, -40
; CHECK-NEXT: aghi %r15, -184
; CHECK-NEXT: .cfi_def_cfa_offset 344
; CHECK-NEXT: lgr %r11, %r15
; CHECK-NEXT: .cfi_def_cfa_register %r11
; CHECK-NEXT: mvhi 180(%r11), 0
; CHECK-NEXT: mvhi 176(%r11), 1
; CHECK-NEXT: mvhi 172(%r11), 2
; CHECK-NEXT: mvhi 168(%r11), 3
; CHECK-NEXT: mvhi 164(%r11), 4
; CHECK-NEXT: lhi %r0, 1
; CHECK-NEXT: strl %r0, x
; CHECK-NEXT: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: mvhi 176(%r11), 1
; CHECK-NEXT: mvhi 172(%r11), 2
; CHECK-NEXT: mvhi 168(%r11), 3
; CHECK-NEXT: lhi %r2, 0
; CHECK-NEXT: mvhi 164(%r11), 4
; CHECK-NEXT: lmg %r11, %r15, 272(%r11)
; CHECK-NEXT: br %r14
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4

store i32 0, i32* %1, align 4
store i32 0, i32* @x, align 4
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
store i32 1, i32* @x, align 4
call void asm sideeffect "", "~{memory},~{dirflag},~{fpsr},~{flags}"()
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
ret i32 0
}

attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
; RUN: llc -enable-machine-outliner -mtriple=wasm32-unknown-linux < %s | FileCheck %s
;
; NOTE: Machine outliner doesn't run.
@x = global i32 0, align 4

define i32 @check_boundaries() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4
store i32 0, i32* %1, align 4
store i32 0, i32* %2, align 4
%6 = load i32, i32* %2, align 4
%7 = icmp ne i32 %6, 0
br i1 %7, label %9, label %8

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %10

store i32 1, i32* %4, align 4
br label %10

%11 = load i32, i32* %2, align 4
%12 = icmp ne i32 %11, 0
br i1 %12, label %14, label %13

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %15

store i32 1, i32* %4, align 4
br label %15

ret i32 0
}

define i32 @main() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4

store i32 0, i32* %1, align 4
store i32 0, i32* @x, align 4
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
store i32 1, i32* @x, align 4
call void asm sideeffect "", "~{memory},~{dirflag},~{fpsr},~{flags}"()
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
ret i32 0
}

attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --include-generated-funcs
; RUN: llc -enable-machine-outliner -mtriple=wasm32-unknown-linux < %s | FileCheck %s
; NOTE: Machine outliner doesn't run.
@x = global i32 0, align 4

define i32 @check_boundaries() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4
store i32 0, i32* %1, align 4
store i32 0, i32* %2, align 4
%6 = load i32, i32* %2, align 4
%7 = icmp ne i32 %6, 0
br i1 %7, label %9, label %8

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %10

store i32 1, i32* %4, align 4
br label %10

%11 = load i32, i32* %2, align 4
%12 = icmp ne i32 %11, 0
br i1 %12, label %14, label %13

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %15

store i32 1, i32* %4, align 4
br label %15

ret i32 0
}

define i32 @main() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4

store i32 0, i32* %1, align 4
store i32 0, i32* @x, align 4
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
store i32 1, i32* @x, align 4
call void asm sideeffect "", "~{memory},~{dirflag},~{fpsr},~{flags}"()
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
ret i32 0
}

attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
; CHECK-LABEL: check_boundaries:
; CHECK: .functype check_boundaries () -> (i32)
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get __stack_pointer
; CHECK-NEXT: i32.const 32
; CHECK-NEXT: i32.sub
; CHECK-NEXT: local.tee 0
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i32.store 24
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i32.store 28
; CHECK-NEXT: block
; CHECK-NEXT: block
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: br_if 0 # 0: down to label1
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 2
; CHECK-NEXT: i32.store 20
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 1
; CHECK-NEXT: i32.store 24
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 3
; CHECK-NEXT: i32.store 16
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 4
; CHECK-NEXT: i32.store 12
; CHECK-NEXT: br 1 # 1: down to label0
; CHECK-NEXT: .LBB0_2:
; CHECK-NEXT: end_block # label1:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 1
; CHECK-NEXT: i32.store 16
; CHECK-NEXT: .LBB0_3:
; CHECK-NEXT: end_block # label0:
; CHECK-NEXT: block
; CHECK-NEXT: block
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.load 24
; CHECK-NEXT: br_if 0 # 0: down to label3
; CHECK-NEXT: # %bb.4:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 2
; CHECK-NEXT: i32.store 20
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 1
; CHECK-NEXT: i32.store 24
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 3
; CHECK-NEXT: i32.store 16
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 4
; CHECK-NEXT: i32.store 12
; CHECK-NEXT: br 1 # 1: down to label2
; CHECK-NEXT: .LBB0_5:
; CHECK-NEXT: end_block # label3:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 1
; CHECK-NEXT: i32.store 16
; CHECK-NEXT: .LBB0_6:
; CHECK-NEXT: end_block # label2:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 32
; CHECK-NEXT: i32.add
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: # fallthrough-return
;
; CHECK-LABEL: __original_main:
; CHECK: .functype __original_main () -> (i32)
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get __stack_pointer
; CHECK-NEXT: i32.const 32
; CHECK-NEXT: i32.sub
; CHECK-NEXT: local.tee 0
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i32.const 1
; CHECK-NEXT: i32.store x
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i32.store 28
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 1
; CHECK-NEXT: i32.store 24
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 2
; CHECK-NEXT: i32.store 20
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 3
; CHECK-NEXT: i32.store 16
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 4
; CHECK-NEXT: i32.store 12
; CHECK-NEXT: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 2
; CHECK-NEXT: i32.store 20
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 1
; CHECK-NEXT: i32.store 24
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 3
; CHECK-NEXT: i32.store 16
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 4
; CHECK-NEXT: i32.store 12
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 32
; CHECK-NEXT: i32.add
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: # fallthrough-return
;
; CHECK-LABEL: main:
; CHECK: .functype main (i32, i32) -> (i32)
; CHECK-NEXT: # %bb.0: # %body
; CHECK-NEXT: call __original_main
; CHECK-NEXT: # fallthrough-return
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -enable-machine-outliner -mtriple=wasm32-unknown-linux < %s | FileCheck %s
;
; NOTE: Machine outliner doesn't run.
@x = global i32 0, align 4

define i32 @check_boundaries() #0 {
; CHECK-LABEL: check_boundaries:
; CHECK: .functype check_boundaries () -> (i32)
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get __stack_pointer
; CHECK-NEXT: i32.const 32
; CHECK-NEXT: i32.sub
; CHECK-NEXT: local.tee 0
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i32.store 24
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i32.store 28
; CHECK-NEXT: block
; CHECK-NEXT: block
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: br_if 0 # 0: down to label1
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 2
; CHECK-NEXT: i32.store 20
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 1
; CHECK-NEXT: i32.store 24
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 3
; CHECK-NEXT: i32.store 16
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 4
; CHECK-NEXT: i32.store 12
; CHECK-NEXT: br 1 # 1: down to label0
; CHECK-NEXT: .LBB0_2:
; CHECK-NEXT: end_block # label1:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 1
; CHECK-NEXT: i32.store 16
; CHECK-NEXT: .LBB0_3:
; CHECK-NEXT: end_block # label0:
; CHECK-NEXT: block
; CHECK-NEXT: block
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.load 24
; CHECK-NEXT: br_if 0 # 0: down to label3
; CHECK-NEXT: # %bb.4:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 2
; CHECK-NEXT: i32.store 20
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 1
; CHECK-NEXT: i32.store 24
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 3
; CHECK-NEXT: i32.store 16
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 4
; CHECK-NEXT: i32.store 12
; CHECK-NEXT: br 1 # 1: down to label2
; CHECK-NEXT: .LBB0_5:
; CHECK-NEXT: end_block # label3:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 1
; CHECK-NEXT: i32.store 16
; CHECK-NEXT: .LBB0_6:
; CHECK-NEXT: end_block # label2:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.const 32
; CHECK-NEXT: i32.add
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: # fallthrough-return
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4
store i32 0, i32* %1, align 4
store i32 0, i32* %2, align 4
%6 = load i32, i32* %2, align 4
%7 = icmp ne i32 %6, 0
br i1 %7, label %9, label %8

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %10

store i32 1, i32* %4, align 4
br label %10

%11 = load i32, i32* %2, align 4
%12 = icmp ne i32 %11, 0
br i1 %12, label %14, label %13

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %15

store i32 1, i32* %4, align 4
br label %15

ret i32 0
}

define i32 @main() #0 {
; CHECK-LABEL: main:
; CHECK: .functype main (i32, i32) -> (i32)
; CHECK-NEXT: # %bb.0: # %body
; CHECK-NEXT: call __original_main
; CHECK-NEXT: # fallthrough-return
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4

store i32 0, i32* %1, align 4
store i32 0, i32* @x, align 4
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
store i32 1, i32* @x, align 4
call void asm sideeffect "", "~{memory},~{dirflag},~{fpsr},~{flags}"()
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
ret i32 0
}

attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
; RUN: llc -enable-machine-outliner -mtriple=x86_64-unknown-linux < %s | FileCheck %s
@x = global i32 0, align 4

define i32 @check_boundaries() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4
store i32 0, i32* %1, align 4
store i32 0, i32* %2, align 4
%6 = load i32, i32* %2, align 4
%7 = icmp ne i32 %6, 0
br i1 %7, label %9, label %8

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %10

store i32 1, i32* %4, align 4
br label %10

%11 = load i32, i32* %2, align 4
%12 = icmp ne i32 %11, 0
br i1 %12, label %14, label %13

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %15

store i32 1, i32* %4, align 4
br label %15

ret i32 0
}

define i32 @main() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4

store i32 0, i32* %1, align 4
store i32 0, i32* @x, align 4
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
store i32 1, i32* @x, align 4
call void asm sideeffect "", "~{memory},~{dirflag},~{fpsr},~{flags}"()
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
ret i32 0
}

attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --include-generated-funcs
; RUN: llc -enable-machine-outliner -mtriple=x86_64-unknown-linux < %s | FileCheck %s
@x = global i32 0, align 4

define i32 @check_boundaries() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4
store i32 0, i32* %1, align 4
store i32 0, i32* %2, align 4
%6 = load i32, i32* %2, align 4
%7 = icmp ne i32 %6, 0
br i1 %7, label %9, label %8

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %10

store i32 1, i32* %4, align 4
br label %10

%11 = load i32, i32* %2, align 4
%12 = icmp ne i32 %11, 0
br i1 %12, label %14, label %13

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %15

store i32 1, i32* %4, align 4
br label %15

ret i32 0
}

define i32 @main() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4

store i32 0, i32* %1, align 4
store i32 0, i32* @x, align 4
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
store i32 1, i32* @x, align 4
call void asm sideeffect "", "~{memory},~{dirflag},~{fpsr},~{flags}"()
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
ret i32 0
}

attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
; CHECK-LABEL: check_boundaries:
; CHECK: # %bb.0:
; CHECK-NEXT: pushq %rbp
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: .cfi_offset %rbp, -16
; CHECK-NEXT: movq %rsp, %rbp
; CHECK-NEXT: .cfi_def_cfa_register %rbp
; CHECK-NEXT: subq $20, %rsp
; CHECK-NEXT: movl $0, -20(%rbp)
; CHECK-NEXT: movl $0, -8(%rbp)
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: testb %al, %al
; CHECK-NEXT: je .LBB0_1
; CHECK-NEXT: # %bb.2:
; CHECK-NEXT: movl $1, -4(%rbp)
; CHECK-NEXT: cmpl $0, -8(%rbp)
; CHECK-NEXT: je .LBB0_4
; CHECK-NEXT: .LBB0_5:
; CHECK-NEXT: movl $1, -4(%rbp)
; CHECK-NEXT: jmp .LBB0_6
; CHECK-NEXT: .LBB0_1:
; CHECK-NEXT: callq OUTLINED_FUNCTION_0
; CHECK-NEXT: cmpl $0, -8(%rbp)
; CHECK-NEXT: jne .LBB0_5
; CHECK-NEXT: .LBB0_4:
; CHECK-NEXT: callq OUTLINED_FUNCTION_0
; CHECK-NEXT: .LBB0_6:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: addq $20, %rsp
; CHECK-NEXT: popq %rbp
; CHECK-NEXT: .cfi_def_cfa %rsp, 8
; CHECK-NEXT: retq
;
; CHECK-LABEL: main:
; CHECK: # %bb.0:
; CHECK-NEXT: pushq %rbp
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: .cfi_offset %rbp, -16
; CHECK-NEXT: movq %rsp, %rbp
; CHECK-NEXT: .cfi_def_cfa_register %rbp
; CHECK-NEXT: subq $20, %rsp
; CHECK-NEXT: movl $0, -20(%rbp)
; CHECK-NEXT: callq OUTLINED_FUNCTION_1
; CHECK-NEXT: movl $1, {{.*}}(%rip)
; CHECK-NEXT: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: callq OUTLINED_FUNCTION_1
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: addq $20, %rsp
; CHECK-NEXT: popq %rbp
; CHECK-NEXT: .cfi_def_cfa %rsp, 8
; CHECK-NEXT: retq
;
; CHECK-LABEL: OUTLINED_FUNCTION_0:
; CHECK: # %bb.0:
; CHECK-NEXT: movl $1, -8(%rbp)
; CHECK-NEXT: movl $2, -16(%rbp)
; CHECK-NEXT: movl $3, -4(%rbp)
; CHECK-NEXT: movl $4, -12(%rbp)
; CHECK-NEXT: retq
;
; CHECK-LABEL: OUTLINED_FUNCTION_1:
; CHECK: # %bb.0:
; CHECK-NEXT: movl $1, -16(%rbp)
; CHECK-NEXT: movl $2, -12(%rbp)
; CHECK-NEXT: movl $3, -8(%rbp)
; CHECK-NEXT: movl $4, -4(%rbp)
; CHECK-NEXT: retq
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -enable-machine-outliner -mtriple=x86_64-unknown-linux < %s | FileCheck %s
@x = global i32 0, align 4

define i32 @check_boundaries() #0 {
; CHECK-LABEL: check_boundaries:
; CHECK: # %bb.0:
; CHECK-NEXT: pushq %rbp
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: .cfi_offset %rbp, -16
; CHECK-NEXT: movq %rsp, %rbp
; CHECK-NEXT: .cfi_def_cfa_register %rbp
; CHECK-NEXT: subq $20, %rsp
; CHECK-NEXT: movl $0, -20(%rbp)
; CHECK-NEXT: movl $0, -8(%rbp)
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: testb %al, %al
; CHECK-NEXT: je .LBB0_1
; CHECK-NEXT: # %bb.2:
; CHECK-NEXT: movl $1, -4(%rbp)
; CHECK-NEXT: cmpl $0, -8(%rbp)
; CHECK-NEXT: je .LBB0_4
; CHECK-NEXT: .LBB0_5:
; CHECK-NEXT: movl $1, -4(%rbp)
; CHECK-NEXT: jmp .LBB0_6
; CHECK-NEXT: .LBB0_1:
; CHECK-NEXT: callq OUTLINED_FUNCTION_0
; CHECK-NEXT: cmpl $0, -8(%rbp)
; CHECK-NEXT: jne .LBB0_5
; CHECK-NEXT: .LBB0_4:
; CHECK-NEXT: callq OUTLINED_FUNCTION_0
; CHECK-NEXT: .LBB0_6:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: addq $20, %rsp
; CHECK-NEXT: popq %rbp
; CHECK-NEXT: .cfi_def_cfa %rsp, 8
; CHECK-NEXT: retq
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4
store i32 0, i32* %1, align 4
store i32 0, i32* %2, align 4
%6 = load i32, i32* %2, align 4
%7 = icmp ne i32 %6, 0
br i1 %7, label %9, label %8

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %10

store i32 1, i32* %4, align 4
br label %10

%11 = load i32, i32* %2, align 4
%12 = icmp ne i32 %11, 0
br i1 %12, label %14, label %13

store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
br label %15

store i32 1, i32* %4, align 4
br label %15

ret i32 0
}

define i32 @main() #0 {
; CHECK-LABEL: main:
; CHECK: # %bb.0:
; CHECK-NEXT: pushq %rbp
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: .cfi_offset %rbp, -16
; CHECK-NEXT: movq %rsp, %rbp
; CHECK-NEXT: .cfi_def_cfa_register %rbp
; CHECK-NEXT: subq $20, %rsp
; CHECK-NEXT: movl $0, -20(%rbp)
; CHECK-NEXT: callq OUTLINED_FUNCTION_1
; CHECK-NEXT: movl $1, {{.*}}(%rip)
; CHECK-NEXT: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: callq OUTLINED_FUNCTION_1
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: addq $20, %rsp
; CHECK-NEXT: popq %rbp
; CHECK-NEXT: .cfi_def_cfa %rsp, 8
; CHECK-NEXT: retq
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i32, align 4

store i32 0, i32* %1, align 4
store i32 0, i32* @x, align 4
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
store i32 1, i32* @x, align 4
call void asm sideeffect "", "~{memory},~{dirflag},~{fpsr},~{flags}"()
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
store i32 4, i32* %5, align 4
ret i32 0
}

attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# REQUIRES: aarch64-registered-target

## Check that generated functions are included.
# RUN: cp -f %S/Inputs/aarch64_generated_funcs.ll %t.ll && %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/aarch64_generated_funcs.ll.generated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/aarch64_generated_funcs.ll.generated.expected

## Check that generated functions are not included.
# RUN: cp -f %S/Inputs/aarch64_generated_funcs.ll %t.ll && %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/aarch64_generated_funcs.ll.nogenerated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/aarch64_generated_funcs.ll.nogenerated.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# REQUIRES: amdgpu-registered-target

## Check that generated functions are included.
# RUN: cp -f %S/Inputs/amdgpu_generated_funcs.ll %t.ll && %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/amdgpu_generated_funcs.ll.generated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/amdgpu_generated_funcs.ll.generated.expected

## Check that generated functions are not included.
# RUN: cp -f %S/Inputs/amdgpu_generated_funcs.ll %t.ll && %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/amdgpu_generated_funcs.ll.nogenerated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/amdgpu_generated_funcs.ll.nogenerated.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# REQUIRES: arm-registered-target

## Check that generated functions are included.
# RUN: cp -f %S/Inputs/arm_generated_funcs.ll %t.ll && %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/arm_generated_funcs.ll.generated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/arm_generated_funcs.ll.generated.expected

## Check that generated functions are not included.
# RUN: cp -f %S/Inputs/arm_generated_funcs.ll %t.ll && %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/arm_generated_funcs.ll.nogenerated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/arm_generated_funcs.ll.nogenerated.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# REQUIRES: hexagon-registered-target

## Check that generated functions are included.
# RUN: cp -f %S/Inputs/hexagon_generated_funcs.ll %t.ll && %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/hexagon_generated_funcs.ll.generated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/hexagon_generated_funcs.ll.generated.expected

## Check that generated functions are not included.
# RUN: cp -f %S/Inputs/hexagon_generated_funcs.ll %t.ll && %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/hexagon_generated_funcs.ll.nogenerated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/hexagon_generated_funcs.ll.nogenerated.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# REQUIRES: lanai-registered-target

## Check that generated functions are included.
# RUN: cp -f %S/Inputs/lanai_generated_funcs.ll %t.ll && %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/lanai_generated_funcs.ll.generated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/lanai_generated_funcs.ll.generated.expected

## Check that generated functions are not included.
# RUN: cp -f %S/Inputs/lanai_generated_funcs.ll %t.ll && %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/lanai_generated_funcs.ll.nogenerated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/lanai_generated_funcs.ll.nogenerated.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# REQUIRES: mips-registered-target

## Check that generated functions are included.
# RUN: cp -f %S/Inputs/mips_generated_funcs.ll %t.ll && %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/mips_generated_funcs.ll.generated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/mips_generated_funcs.ll.generated.expected

## Check that generated functions are not included.
# RUN: cp -f %S/Inputs/mips_generated_funcs.ll %t.ll && %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/mips_generated_funcs.ll.nogenerated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/mips_generated_funcs.ll.nogenerated.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# REQUIRES: msp430-registered-target

## Check that generated functions are included.
# RUN: cp -f %S/Inputs/msp430_generated_funcs.ll %t.ll && %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/msp430_generated_funcs.ll.generated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/msp430_generated_funcs.ll.generated.expected

## Check that generated functions are not included.
# RUN: cp -f %S/Inputs/msp430_generated_funcs.ll %t.ll && %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/msp430_generated_funcs.ll.nogenerated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/msp430_generated_funcs.ll.nogenerated.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# REQUIRES: powerpc-registered-target

## Check that generated functions are included.
# RUN: cp -f %S/Inputs/ppc_generated_funcs.ll %t.ll && %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/ppc_generated_funcs.ll.generated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/ppc_generated_funcs.ll.generated.expected

## Check that generated functions are not included.
# RUN: cp -f %S/Inputs/ppc_generated_funcs.ll %t.ll && %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/ppc_generated_funcs.ll.nogenerated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/ppc_generated_funcs.ll.nogenerated.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# REQUIRES: riscv-registered-target

## Check that generated functions are included.
# RUN: cp -f %S/Inputs/riscv_generated_funcs.ll %t.ll && %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/riscv_generated_funcs.ll.generated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/riscv_generated_funcs.ll.generated.expected

## Check that generated functions are not included.
# RUN: cp -f %S/Inputs/riscv_generated_funcs.ll %t.ll && %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/riscv_generated_funcs.ll.nogenerated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/riscv_generated_funcs.ll.nogenerated.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# REQUIRES: sparc-registered-target

## Check that generated functions are included.
# RUN: cp -f %S/Inputs/sparc_generated_funcs.ll %t.ll && %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/sparc_generated_funcs.ll.generated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/sparc_generated_funcs.ll.generated.expected

## Check that generated functions are not included.
# RUN: cp -f %S/Inputs/sparc_generated_funcs.ll %t.ll && %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/sparc_generated_funcs.ll.nogenerated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/sparc_generated_funcs.ll.nogenerated.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# REQUIRES: systemz-registered-target

## Check that generated functions are included.
# RUN: cp -f %S/Inputs/systemz_generated_funcs.ll %t.ll && %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/systemz_generated_funcs.ll.generated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/systemz_generated_funcs.ll.generated.expected

## Check that generated functions are not included.
# RUN: cp -f %S/Inputs/systemz_generated_funcs.ll %t.ll && %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/systemz_generated_funcs.ll.nogenerated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/systemz_generated_funcs.ll.nogenerated.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# REQUIRES: webassembly-registered-target

## Check that generated functions are included.
# RUN: cp -f %S/Inputs/wasm_generated_funcs.ll %t.ll && %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/wasm_generated_funcs.ll.generated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/wasm_generated_funcs.ll.generated.expected

## Check that generated functions are not included.
# RUN: cp -f %S/Inputs/wasm_generated_funcs.ll %t.ll && %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/wasm_generated_funcs.ll.nogenerated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/wasm_generated_funcs.ll.nogenerated.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# REQUIRES: x86-registered-target

## Check that generated functions are included.
# RUN: cp -f %S/Inputs/x86_generated_funcs.ll %t.ll && %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/x86_generated_funcs.ll.generated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/x86_generated_funcs.ll.generated.expected

## Check that generated functions are not included.
# RUN: cp -f %S/Inputs/x86_generated_funcs.ll %t.ll && %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/x86_generated_funcs.ll.nogenerated.expected

## Check that running the script again does not change the result:
# RUN: %update_llc_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/x86_generated_funcs.ll.nogenerated.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
; RUN: opt -hotcoldsplit -hotcoldsplit-threshold=0 -S < %s | FileCheck %s
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.14.0"

define void @foo(i32) {
%2 = icmp eq i32 %0, 0
tail call void @_Z10sideeffectv()
br i1 %2, label %sink, label %exit

sink:
tail call void @_Z10sideeffectv()
call void @llvm.trap()
unreachable

exit:
ret void
}

define void @bar(i32) {
%2 = icmp eq i32 %0, 0
tail call void @_Z10sideeffectv()
br i1 %2, label %sink, label %exit

sink:
tail call void @_Z10sideeffectv()
call void @llvm.trap()
unreachable

exit:
ret void
}

declare void @llvm.trap() noreturn cold
declare void @_Z10sideeffectv()
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
; RUN: opt -hotcoldsplit -hotcoldsplit-threshold=0 -S < %s | FileCheck %s
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.14.0"

define void @foo(i32) {
%2 = icmp eq i32 %0, 0
tail call void @_Z10sideeffectv()
br i1 %2, label %sink, label %exit

sink:
tail call void @_Z10sideeffectv()
call void @llvm.trap()
unreachable

exit:
ret void
}

define void @bar(i32) {
%2 = icmp eq i32 %0, 0
tail call void @_Z10sideeffectv()
br i1 %2, label %sink, label %exit

sink:
tail call void @_Z10sideeffectv()
call void @llvm.trap()
unreachable

exit:
ret void
}

declare void @llvm.trap() noreturn cold
declare void @_Z10sideeffectv()
; CHECK-LABEL: @foo(
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0:%.*]], 0
; CHECK-NEXT: tail call void @_Z10sideeffectv()
; CHECK-NEXT: br i1 [[TMP2]], label [[CODEREPL:%.*]], label [[EXIT:%.*]]
; CHECK: codeRepl:
; CHECK-NEXT: call void @foo.cold.1() [[ATTR2:#.*]]
; CHECK-NEXT: ret void
; CHECK: exit:
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: @bar(
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0:%.*]], 0
; CHECK-NEXT: tail call void @_Z10sideeffectv()
; CHECK-NEXT: br i1 [[TMP2]], label [[CODEREPL:%.*]], label [[EXIT:%.*]]
; CHECK: codeRepl:
; CHECK-NEXT: call void @bar.cold.1() [[ATTR2]]
; CHECK-NEXT: ret void
; CHECK: exit:
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: @foo.cold.1(
; CHECK-NEXT: newFuncRoot:
; CHECK-NEXT: br label [[SINK:%.*]]
; CHECK: sink:
; CHECK-NEXT: tail call void @_Z10sideeffectv()
; CHECK-NEXT: call void @llvm.trap()
; CHECK-NEXT: unreachable
;
;
; CHECK-LABEL: @bar.cold.1(
; CHECK-NEXT: newFuncRoot:
; CHECK-NEXT: br label [[SINK:%.*]]
; CHECK: sink:
; CHECK-NEXT: tail call void @_Z10sideeffectv()
; CHECK-NEXT: call void @llvm.trap()
; CHECK-NEXT: unreachable
;
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -hotcoldsplit -hotcoldsplit-threshold=0 -S < %s | FileCheck %s
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.14.0"

define void @foo(i32) {
; CHECK-LABEL: @foo(
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0:%.*]], 0
; CHECK-NEXT: tail call void @_Z10sideeffectv()
; CHECK-NEXT: br i1 [[TMP2]], label [[CODEREPL:%.*]], label [[EXIT:%.*]]
; CHECK: codeRepl:
; CHECK-NEXT: call void @foo.cold.1() [[ATTR2:#.*]]
; CHECK-NEXT: ret void
; CHECK: exit:
; CHECK-NEXT: ret void
;
%2 = icmp eq i32 %0, 0
tail call void @_Z10sideeffectv()
br i1 %2, label %sink, label %exit

sink:
tail call void @_Z10sideeffectv()
call void @llvm.trap()
unreachable

exit:
ret void
}

define void @bar(i32) {
; CHECK-LABEL: @bar(
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0:%.*]], 0
; CHECK-NEXT: tail call void @_Z10sideeffectv()
; CHECK-NEXT: br i1 [[TMP2]], label [[CODEREPL:%.*]], label [[EXIT:%.*]]
; CHECK: codeRepl:
; CHECK-NEXT: call void @bar.cold.1() [[ATTR2]]
; CHECK-NEXT: ret void
; CHECK: exit:
; CHECK-NEXT: ret void
;
%2 = icmp eq i32 %0, 0
tail call void @_Z10sideeffectv()
br i1 %2, label %sink, label %exit

sink:
tail call void @_Z10sideeffectv()
call void @llvm.trap()
unreachable

exit:
ret void
}

declare void @llvm.trap() noreturn cold
declare void @_Z10sideeffectv()
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## Check that generated functions are included.
# RUN: cp -f %S/Inputs/generated_funcs.ll %t.ll && %update_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/generated_funcs.ll.generated.expected

## Check that running the script again does not change the result:
# RUN: %update_test_checks --include-generated-funcs %t.ll
# RUN: diff -u %t.ll %S/Inputs/generated_funcs.ll.generated.expected

## Check that generated functions are not included.
# RUN: cp -f %S/Inputs/generated_funcs.ll %t.ll && %update_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/generated_funcs.ll.nogenerated.expected

## Check that running the script again does not change the result:
# RUN: %update_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/generated_funcs.ll.nogenerated.expected
9 changes: 5 additions & 4 deletions llvm/utils/UpdateTestChecks/asm.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class string:
##### Assembly parser

ASM_FUNCTION_X86_RE = re.compile(
r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n(?:\s*\.?Lfunc_begin[^:\n]*:\n)?[^:]*?'
r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*(@"?(?P=func)"?| -- Begin function (?P=func))\n(?:\s*\.?Lfunc_begin[^:\n]*:\n)?[^:]*?'
r'(?P<body>^##?[ \t]+[^:]+:.*?)\s*'
r'^\s*(?:[^:\n]+?:\s*\n\s*\.size|\.cfi_endproc|\.globl|\.comm|\.(?:sub)?section|#+ -- End function)',
flags=(re.M | re.S))
Expand All @@ -28,7 +28,7 @@ class string:
flags=(re.M | re.S))

ASM_FUNCTION_AARCH64_RE = re.compile(
r'^_?(?P<func>[^:]+):[ \t]*\/\/[ \t]*@"?(?P=func)"?\n'
r'^_?(?P<func>[^:]+):[ \t]*\/\/[ \t]*@"?(?P=func)"?( (Function|Tail Call))?\n'
r'(?:[ \t]+.cfi_startproc\n)?' # drop optional cfi noise
r'(?P<body>.*?)\n'
# This list is incomplete
Expand Down Expand Up @@ -323,7 +323,8 @@ def get_triple_from_march(march):
print("Cannot find a triple. Assume 'x86'", file=sys.stderr)
return 'x86'

def build_function_body_dictionary_for_triple(args, raw_tool_output, triple, prefixes, func_dict):
def build_function_body_dictionary_for_triple(args, raw_tool_output, triple,
prefixes, func_dict, func_order):
target_handlers = {
'i686': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
'x86': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
Expand Down Expand Up @@ -366,7 +367,7 @@ def build_function_body_dictionary_for_triple(args, raw_tool_output, triple, pre
scrubber, function_re = handler
common.build_function_body_dictionary(
function_re, scrubber, [args], raw_tool_output, prefixes,
func_dict, args.verbose, False, False)
func_dict, func_order, args.verbose, False, False)

##### Generator of assembly CHECK lines

Expand Down
84 changes: 78 additions & 6 deletions llvm/utils/UpdateTestChecks/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class string:
_verbose = False

def parse_commandline_args(parser):
parser.add_argument('--include-generated-funcs', action='store_true',
help='Output checks for functions not in source')
parser.add_argument('-v', '--verbose', action='store_true',
help='Show verbose output')
parser.add_argument('-u', '--update-only', action='store_true',
Expand Down Expand Up @@ -62,19 +64,25 @@ def __init__(self, test, parser, script_name, input_lines, args, argv,
self.test_autogenerated_note = self.autogenerated_note_prefix + script_name
self.test_autogenerated_note += get_autogennote_suffix(parser, self.args)

def ro_iterlines(self):
for line_num, input_line in enumerate(self.input_lines):
args, argv = check_for_command(input_line, self.parser,
self.args, self.argv, self.argparse_callback)
yield InputLineInfo(input_line, line_num, args, argv)

def iterlines(self, output_lines):
output_lines.append(self.test_autogenerated_note)
for line_num, input_line in enumerate(self.input_lines):
for line_info in self.ro_iterlines():
input_line = line_info.line
# Discard any previous script advertising.
if input_line.startswith(self.autogenerated_note_prefix):
continue
self.args, self.argv = check_for_command(input_line, self.parser,
self.args, self.argv, self.argparse_callback)
self.args = line_info.args
self.argv = line_info.argv
if not self.args.enabled:
output_lines.append(input_line)
continue
yield InputLineInfo(input_line, line_num, self.args, self.argv)

yield line_info

def itertests(test_patterns, parser, script_name, comment_prefix=None, argparse_callback=None):
for pattern in test_patterns:
Expand Down Expand Up @@ -250,7 +258,7 @@ def repl_arg_names(match):
def __str__(self):
return self.scrub

def build_function_body_dictionary(function_re, scrubber, scrubber_args, raw_tool_output, prefixes, func_dict, verbose, record_args, check_attributes):
def build_function_body_dictionary(function_re, scrubber, scrubber_args, raw_tool_output, prefixes, func_dict, func_order, verbose, record_args, check_attributes):
for m in function_re.finditer(raw_tool_output):
if not m:
continue
Expand Down Expand Up @@ -292,6 +300,7 @@ def build_function_body_dictionary(function_re, scrubber, scrubber_args, raw_too
continue

func_dict[prefix][func] = function_body(scrubbed_body, scrubbed_extra, args_and_sig, attrs)
func_order[prefix].append(func)

##### Generator of LLVM IR CHECK lines

Expand Down Expand Up @@ -594,3 +603,66 @@ def check_for_command(line, parser, args, argv, argparse_callback):
if argparse_callback is not None:
argparse_callback(args)
return args, argv

def find_arg_in_test(test_info, get_arg_to_check, arg_string, is_global):
result = get_arg_to_check(test_info.args)
if not result and is_global:
# See if this has been specified via UTC_ARGS. This is a "global" option
# that affects the entire generation of test checks. If it exists anywhere
# in the test, apply it to everything.
saw_line = False
for line_info in test_info.ro_iterlines():
line = line_info.line
if not line.startswith(';') and line.strip() != '':
saw_line = True
result = get_arg_to_check(line_info.args)
if result:
if warn and saw_line:
# We saw the option after already reading some test input lines.
# Warn about it.
print('WARNING: Found {} in line following test start: '.format(arg_string)
+ line, file=sys.stderr)
print('WARNING: Consider moving {} to top of file'.format(arg_string),
file=sys.stderr)
break
return result

def dump_input_lines(output_lines, test_info, prefix_set, comment_string):
for input_line_info in test_info.iterlines(output_lines):
line = input_line_info.line
args = input_line_info.args
if line.strip() == comment_string:
continue
if line.lstrip().startswith(comment_string):
m = CHECK_RE.match(line)
if m and m.group(1) in prefix_set:
continue
output_lines.append(line.rstrip('\n'))

def add_checks_at_end(output_lines, prefix_list, func_order,
comment_string, check_generator):
added = set()
for prefixes, tool_args, *rest in prefix_list:
for prefix in prefixes:
for func in func_order[prefix]:
if added:
output_lines.append(comment_string)
added.add(func)

# The add_*_checks routines expect a run list whose items are
# tuples that have a list of prefixes as their first element and
# tool command args string as their second element. They output
# checks for each prefix in the list of prefixes. By doing so, it
# implicitly assumes that for each function every run line will
# generate something for that function. That is not the case for
# generated functions as some run lines might not generate them
# (e.g. -fopenmp vs. no -fopenmp).
#
# Therefore, pass just the prefix we're interested in. This has
# the effect of generating all of the checks for functions of a
# single prefix before moving on to the next prefix. So checks
# are ordered by prefix instead of by function as in "normal"
# mode.
check_generator(output_lines,
[([prefix], tool_args)],
func)
117 changes: 80 additions & 37 deletions llvm/utils/update_cc_test_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ def config():
return args, parser


def get_function_body(args, filename, clang_args, extra_commands, prefixes, triple_in_cmd, func_dict):
def get_function_body(args, filename, clang_args, extra_commands, prefixes,
triple_in_cmd, func_dict, func_order):
# TODO Clean up duplication of asm/common build_function_body_dictionary
# Invoke external tool and extract function bodies.
raw_tool_output = common.invoke_tool(args.clang, clang_args, filename)
Expand All @@ -196,7 +197,8 @@ def get_function_body(args, filename, clang_args, extra_commands, prefixes, trip
if '-emit-llvm' in clang_args:
common.build_function_body_dictionary(
common.OPT_FUNCTION_RE, common.scrub_body, [],
raw_tool_output, prefixes, func_dict, args.verbose, args.function_signature, args.check_attributes)
raw_tool_output, prefixes, func_dict, func_order, args.verbose,
args.function_signature, args.check_attributes)
else:
print('The clang command line should include -emit-llvm as asm tests '
'are discouraged in Clang testsuite.', file=sys.stderr)
Expand Down Expand Up @@ -247,15 +249,18 @@ def main():

# Execute clang, generate LLVM IR, and extract functions.
func_dict = {}
func_order = {}
for p in run_list:
prefixes = p[0]
for prefix in prefixes:
func_dict.update({prefix: dict()})
func_order.update({prefix: []})
for prefixes, clang_args, extra_commands, triple_in_cmd in run_list:
common.debug('Extracted clang cmd: clang {}'.format(clang_args))
common.debug('Extracted FileCheck prefixes: {}'.format(prefixes))

get_function_body(ti.args, ti.path, clang_args, extra_commands, prefixes, triple_in_cmd, func_dict)
get_function_body(ti.args, ti.path, clang_args, extra_commands, prefixes,
triple_in_cmd, func_dict, func_order)

# Invoke clang -Xclang -ast-dump=json to get mapping from start lines to
# mangled names. Forward all clang args for now.
Expand All @@ -265,41 +270,79 @@ def main():
global_vars_seen_dict = {}
prefix_set = set([prefix for p in run_list for prefix in p[0]])
output_lines = []
for line_info in ti.iterlines(output_lines):
idx = line_info.line_number
line = line_info.line
args = line_info.args
include_line = True
m = common.CHECK_RE.match(line)
if m and m.group(1) in prefix_set:
continue # Don't append the existing CHECK lines
if idx in line2spell_and_mangled_list:
added = set()
for spell, mangled in line2spell_and_mangled_list[idx]:
# One line may contain multiple function declarations.
# Skip if the mangled name has been added before.
# The line number may come from an included file,
# we simply require the spelling name to appear on the line
# to exclude functions from other files.
if mangled in added or spell not in line:
continue
if args.functions is None or any(re.search(regex, spell) for regex in args.functions):
last_line = output_lines[-1].strip()
while last_line == '//':
# Remove the comment line since we will generate a new comment
# line as part of common.add_ir_checks()
output_lines.pop()

include_generated_funcs = common.find_arg_in_test(ti,
lambda args: ti.args.include_generated_funcs,
'--include-generated-funcs',
True)

if include_generated_funcs:
# Generate the appropriate checks for each function. We need to emit
# these in the order according to the generated output so that CHECK-LABEL
# works properly. func_order provides that.

# It turns out that when clang generates functions (for example, with
# -fopenmp), it can sometimes cause functions to be re-ordered in the
# output, even functions that exist in the source file. Therefore we
# can't insert check lines before each source function and instead have to
# put them at the end. So the first thing to do is dump out the source
# lines.
common.dump_input_lines(output_lines, ti, prefix_set, '//')

# Now generate all the checks.
def check_generator(my_output_lines, prefixes, func):
if '-emit-llvm' in clang_args:
common.add_ir_checks(my_output_lines, '//',
prefixes,
func_dict, func, False,
ti.args.function_signature,
global_vars_seen_dict)
else:
asm.add_asm_checks(my_output_lines, '//',
prefixes,
func_dict, func)

common.add_checks_at_end(output_lines, run_list, func_order, '//',
lambda my_output_lines, prefixes, func:
check_generator(my_output_lines,
prefixes, func))
else:
# Normal mode. Put checks before each source function.
for line_info in ti.iterlines(output_lines):
idx = line_info.line_number
line = line_info.line
args = line_info.args
include_line = True
m = common.CHECK_RE.match(line)
if m and m.group(1) in prefix_set:
continue # Don't append the existing CHECK lines
if idx in line2spell_and_mangled_list:
added = set()
for spell, mangled in line2spell_and_mangled_list[idx]:
# One line may contain multiple function declarations.
# Skip if the mangled name has been added before.
# The line number may come from an included file,
# we simply require the spelling name to appear on the line
# to exclude functions from other files.
if mangled in added or spell not in line:
continue
if args.functions is None or any(re.search(regex, spell) for regex in args.functions):
last_line = output_lines[-1].strip()
if added:
output_lines.append('//')
added.add(mangled)
common.add_ir_checks(output_lines, '//', run_list, func_dict, mangled,
False, args.function_signature, global_vars_seen_dict)
if line.rstrip('\n') == '//':
include_line = False

if include_line:
output_lines.append(line.rstrip('\n'))
while last_line == '//':
# Remove the comment line since we will generate a new comment
# line as part of common.add_ir_checks()
output_lines.pop()
last_line = output_lines[-1].strip()
if added:
output_lines.append('//')
added.add(mangled)
common.add_ir_checks(output_lines, '//', run_list, func_dict, mangled,
False, args.function_signature, global_vars_seen_dict)
if line.rstrip('\n') == '//':
include_line = False

if include_line:
output_lines.append(line.rstrip('\n'))

common.debug('Writing %d lines to %s...' % (len(output_lines), ti.path))
with open(ti.path, 'wb') as f:
Expand Down
92 changes: 59 additions & 33 deletions llvm/utils/update_llc_test_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,12 @@ def main():
check_indent = ''

func_dict = {}
func_order = {}
for p in run_list:
prefixes = p[0]
for prefix in prefixes:
func_dict.update({prefix: dict()})
func_order.update({prefix: []})
for prefixes, llc_args, triple_in_cmd, march_in_cmd in run_list:
common.debug('Extracted LLC cmd:', llc_tool, llc_args)
common.debug('Extracted FileCheck prefixes:', str(prefixes))
Expand All @@ -114,51 +116,75 @@ def main():
triple = asm.get_triple_from_march(march_in_cmd)

asm.build_function_body_dictionary_for_triple(ti.args, raw_tool_output,
triple, prefixes, func_dict)
triple, prefixes, func_dict, func_order)

is_in_function = False
is_in_function_start = False
func_name = None
prefix_set = set([prefix for p in run_list for prefix in p[0]])
common.debug('Rewriting FileCheck prefixes:', str(prefix_set))
output_lines = []
for input_info in ti.iterlines(output_lines):
input_line = input_info.line
args = input_info.args
if is_in_function_start:
if input_line == '':
continue
if input_line.lstrip().startswith(';'):
m = common.CHECK_RE.match(input_line)
if not m or m.group(1) not in prefix_set:

include_generated_funcs = common.find_arg_in_test(ti,
lambda args: ti.args.include_generated_funcs,
'--include-generated-funcs',
True)

if include_generated_funcs:
# Generate the appropriate checks for each function. We need to emit
# these in the order according to the generated output so that CHECK-LABEL
# works properly. func_order provides that.

# We can't predict where various passes might insert functions so we can't
# be sure the input function order is maintained. Therefore, first spit
# out all the source lines.
common.dump_input_lines(output_lines, ti, prefix_set, ';')

# Now generate all the checks.
common.add_checks_at_end(output_lines, run_list, func_order,
check_indent + ';',
lambda my_output_lines, prefixes, func:
asm.add_asm_checks(my_output_lines,
check_indent + ';',
prefixes, func_dict, func))
else:
for input_info in ti.iterlines(output_lines):
input_line = input_info.line
args = input_info.args
if is_in_function_start:
if input_line == '':
continue
if input_line.lstrip().startswith(';'):
m = common.CHECK_RE.match(input_line)
if not m or m.group(1) not in prefix_set:
output_lines.append(input_line)
continue

# Print out the various check lines here.
asm.add_asm_checks(output_lines, check_indent + ';', run_list, func_dict, func_name)
is_in_function_start = False

if is_in_function:
if common.should_add_line_to_output(input_line, prefix_set):
# This input line of the function body will go as-is into the output.
output_lines.append(input_line)
else:
continue

# Print out the various check lines here.
asm.add_asm_checks(output_lines, check_indent + ';', run_list, func_dict, func_name)
is_in_function_start = False

if is_in_function:
if common.should_add_line_to_output(input_line, prefix_set):
# This input line of the function body will go as-is into the output.
output_lines.append(input_line)
else:
if input_line.strip() == '}':
is_in_function = False
continue
if input_line.strip() == '}':
is_in_function = False
continue

# If it's outside a function, it just gets copied to the output.
output_lines.append(input_line)
# If it's outside a function, it just gets copied to the output.
output_lines.append(input_line)

m = common.IR_FUNCTION_RE.match(input_line)
if not m:
continue
func_name = m.group(1)
if args.function is not None and func_name != args.function:
# When filtering on a specific function, skip all others.
continue
is_in_function = is_in_function_start = True
m = common.IR_FUNCTION_RE.match(input_line)
if not m:
continue
func_name = m.group(1)
if args.function is not None and func_name != args.function:
# When filtering on a specific function, skip all others.
continue
is_in_function = is_in_function_start = True

common.debug('Writing %d lines to %s...' % (len(output_lines), ti.path))

Expand Down
102 changes: 65 additions & 37 deletions llvm/utils/update_test_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,65 +103,93 @@ def main():

global_vars_seen_dict = {}
func_dict = {}
func_order = {}
for prefixes, _ in prefix_list:
for prefix in prefixes:
func_dict.update({prefix: dict()})
func_order.update({prefix: []})
for prefixes, opt_args in prefix_list:
common.debug('Extracted opt cmd: ' + opt_basename + ' ' + opt_args)
common.debug('Extracted FileCheck prefixes: ' + str(prefixes))

raw_tool_output = common.invoke_tool(ti.args.opt_binary, opt_args, ti.path)
common.build_function_body_dictionary(
common.OPT_FUNCTION_RE, common.scrub_body, [],
raw_tool_output, prefixes, func_dict, ti.args.verbose,
raw_tool_output, prefixes, func_dict, func_order, ti.args.verbose,
ti.args.function_signature, ti.args.check_attributes)

is_in_function = False
is_in_function_start = False
prefix_set = set([prefix for prefixes, _ in prefix_list for prefix in prefixes])
common.debug('Rewriting FileCheck prefixes:', str(prefix_set))
output_lines = []
for input_line_info in ti.iterlines(output_lines):
input_line = input_line_info.line
args = input_line_info.args
if is_in_function_start:
if input_line == '':
continue
if input_line.lstrip().startswith(';'):
m = common.CHECK_RE.match(input_line)
if not m or m.group(1) not in prefix_set:

include_generated_funcs = common.find_arg_in_test(ti,
lambda args: ti.args.include_generated_funcs,
'--include-generated-funcs',
True)

if include_generated_funcs:
# Generate the appropriate checks for each function. We need to emit
# these in the order according to the generated output so that CHECK-LABEL
# works properly. func_order provides that.

# We can't predict where various passes might insert functions so we can't
# be sure the input function order is maintained. Therefore, first spit
# out all the source lines.
common.dump_input_lines(output_lines, ti, prefix_set, ';')

# Now generate all the checks.
common.add_checks_at_end(output_lines, prefix_list, func_order, ';',
lambda my_output_lines, prefixes, func:
common.add_ir_checks(my_output_lines, ';',
prefixes,
func_dict, func, False,
ti.args.function_signature,
global_vars_seen_dict))
else:
# "Normal" mode.
for input_line_info in ti.iterlines(output_lines):
input_line = input_line_info.line
args = input_line_info.args
if is_in_function_start:
if input_line == '':
continue
if input_line.lstrip().startswith(';'):
m = common.CHECK_RE.match(input_line)
if not m or m.group(1) not in prefix_set:
output_lines.append(input_line)
continue

# Print out the various check lines here.
common.add_ir_checks(output_lines, ';', prefix_list, func_dict,
func_name, args.preserve_names, args.function_signature,
global_vars_seen_dict)
is_in_function_start = False

if is_in_function:
if common.should_add_line_to_output(input_line, prefix_set):
# This input line of the function body will go as-is into the output.
# Except make leading whitespace uniform: 2 spaces.
input_line = common.SCRUB_LEADING_WHITESPACE_RE.sub(r' ', input_line)
output_lines.append(input_line)
else:
continue

# Print out the various check lines here.
common.add_ir_checks(output_lines, ';', prefix_list, func_dict,
func_name, args.preserve_names, args.function_signature,
global_vars_seen_dict)
is_in_function_start = False

if is_in_function:
if common.should_add_line_to_output(input_line, prefix_set):
# This input line of the function body will go as-is into the output.
# Except make leading whitespace uniform: 2 spaces.
input_line = common.SCRUB_LEADING_WHITESPACE_RE.sub(r' ', input_line)
output_lines.append(input_line)
else:
if input_line.strip() == '}':
is_in_function = False
continue
if input_line.strip() == '}':
is_in_function = False
continue

# If it's outside a function, it just gets copied to the output.
output_lines.append(input_line)
# If it's outside a function, it just gets copied to the output.
output_lines.append(input_line)

m = common.IR_FUNCTION_RE.match(input_line)
if not m:
continue
func_name = m.group(1)
if args.function is not None and func_name != args.function:
# When filtering on a specific function, skip all others.
continue
is_in_function = is_in_function_start = True
m = common.IR_FUNCTION_RE.match(input_line)
if not m:
continue
func_name = m.group(1)
if args.function is not None and func_name != args.function:
# When filtering on a specific function, skip all others.
continue
is_in_function = is_in_function_start = True

common.debug('Writing %d lines to %s...' % (len(output_lines), ti.path))

Expand Down