| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 
 | ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
; RUN: opt < %s -passes=globalopt -S | FileCheck %s
declare token @llvm.call.preallocated.setup(i32)
declare ptr @llvm.call.preallocated.arg(token, i32)
declare i32 @__CxxFrameHandler3(...)
; Don't touch functions with any musttail calls
define internal i32 @preallocated_musttail(ptr preallocated(i32) %p) {
; CHECK-LABEL: define {{[^@]+}}@preallocated_musttail
; CHECK-SAME: (ptr preallocated(i32) [[P:%.*]]) unnamed_addr {
; CHECK-NEXT:    [[RV:%.*]] = load i32, ptr [[P]], align 4
; CHECK-NEXT:    ret i32 [[RV]]
;
  %rv = load i32, ptr %p
  ret i32 %rv
}
define i32 @call_preallocated_musttail(ptr preallocated(i32) %a) {
; CHECK-LABEL: define {{[^@]+}}@call_preallocated_musttail
; CHECK-SAME: (ptr preallocated(i32) [[A:%.*]]) local_unnamed_addr {
; CHECK-NEXT:    [[R:%.*]] = musttail call i32 @preallocated_musttail(ptr preallocated(i32) [[A]])
; CHECK-NEXT:    ret i32 [[R]]
;
  %r = musttail call i32 @preallocated_musttail(ptr preallocated(i32) %a)
  ret i32 %r
}
define i32 @call_preallocated_musttail_without_musttail() {
; CHECK-LABEL: define {{[^@]+}}@call_preallocated_musttail_without_musttail() local_unnamed_addr {
; CHECK-NEXT:    [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 1)
; CHECK-NEXT:    [[N:%.*]] = call ptr @llvm.call.preallocated.arg(token [[C]], i32 0) #[[ATTR1:[0-9]+]]
; CHECK-NEXT:    [[R:%.*]] = call i32 @preallocated_musttail(ptr preallocated(i32) [[N]]) [ "preallocated"(token [[C]]) ]
; CHECK-NEXT:    ret i32 [[R]]
;
  %c = call token @llvm.call.preallocated.setup(i32 1)
  %N = call ptr @llvm.call.preallocated.arg(token %c, i32 0) preallocated(i32)
  %r = call i32 @preallocated_musttail(ptr preallocated(i32) %N) ["preallocated"(token %c)]
  ret i32 %r
}
; Check that only one alloca per preallocated arg
define internal i32 @preallocated(ptr preallocated(i32) %a) {
; CHECK-LABEL: define {{[^@]+}}@preallocated
; CHECK-SAME: (ptr [[A:%.*]]) unnamed_addr {
; CHECK-NEXT:    [[RV:%.*]] = load i32, ptr [[A]], align 4
; CHECK-NEXT:    ret i32 [[RV]]
;
  %rv = load i32, ptr %a
  ret i32 %rv
}
declare void @foo(ptr)
define i32 @call_preallocated_multiple_args() {
; CHECK-LABEL: define {{[^@]+}}@call_preallocated_multiple_args() local_unnamed_addr {
; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @llvm.stacksave.p0()
; CHECK-NEXT:    [[PAARG:%.*]] = alloca i32, align 4
; CHECK-NEXT:    call void @foo(ptr [[PAARG]])
; CHECK-NEXT:    call void @foo(ptr [[PAARG]])
; CHECK-NEXT:    call void @foo(ptr [[PAARG]])
; CHECK-NEXT:    [[R:%.*]] = call fastcc i32 @preallocated(ptr [[PAARG]])
; CHECK-NEXT:    call void @llvm.stackrestore.p0(ptr [[TMP1]])
; CHECK-NEXT:    ret i32 [[R]]
;
  %c = call token @llvm.call.preallocated.setup(i32 1)
  %a1 = call ptr @llvm.call.preallocated.arg(token %c, i32 0) preallocated(i32)
  call void @foo(ptr %a1)
  %a2 = call ptr @llvm.call.preallocated.arg(token %c, i32 0) preallocated(i32)
  call void @foo(ptr %a2)
  %a3 = call ptr @llvm.call.preallocated.arg(token %c, i32 0) preallocated(i32)
  call void @foo(ptr %a3)
  %r = call i32 @preallocated(ptr preallocated(i32) %a3) ["preallocated"(token %c)]
  ret i32 %r
}
; Don't touch functions with any invokes
define internal i32 @preallocated_invoke(ptr preallocated(i32) %p) {
; CHECK-LABEL: define {{[^@]+}}@preallocated_invoke
; CHECK-SAME: (ptr preallocated(i32) [[P:%.*]]) unnamed_addr {
; CHECK-NEXT:    [[RV:%.*]] = load i32, ptr [[P]], align 4
; CHECK-NEXT:    ret i32 [[RV]]
;
  %rv = load i32, ptr %p
  ret i32 %rv
}
define i32 @call_preallocated_invoke() personality ptr @__CxxFrameHandler3 {
; CHECK-LABEL: define {{[^@]+}}@call_preallocated_invoke() local_unnamed_addr personality ptr @__CxxFrameHandler3 {
; CHECK-NEXT:    [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 1)
; CHECK-NEXT:    [[A:%.*]] = call ptr @llvm.call.preallocated.arg(token [[C]], i32 0) #[[ATTR1]]
; CHECK-NEXT:    [[R:%.*]] = invoke i32 @preallocated_invoke(ptr preallocated(i32) [[A]]) [ "preallocated"(token [[C]]) ]
; CHECK-NEXT:    to label [[CONTA:%.*]] unwind label [[CONTB:%.*]]
; CHECK:       conta:
; CHECK-NEXT:    ret i32 [[R]]
; CHECK:       contb:
; CHECK-NEXT:    [[S:%.*]] = catchswitch within none [label %catch] unwind to caller
; CHECK:       catch:
; CHECK-NEXT:    [[P:%.*]] = catchpad within [[S]] []
; CHECK-NEXT:    catchret from [[P]] to label [[CONT:%.*]]
; CHECK:       cont:
; CHECK-NEXT:    ret i32 42
;
  %c = call token @llvm.call.preallocated.setup(i32 1)
  %a = call ptr @llvm.call.preallocated.arg(token %c, i32 0) preallocated(i32)
  %r = invoke i32 @preallocated_invoke(ptr preallocated(i32) %a) ["preallocated"(token %c)]
  to label %conta unwind label %contb
conta:
  ret i32 %r
contb:
  %s = catchswitch within none [label %catch] unwind to caller
catch:
  %p = catchpad within %s []
  catchret from %p to label %cont
cont:
  ret i32 42
}
 |