[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / Inline / dynamic-alloca-simplified-large.ll
blobfd5b40cb876caed332a0d1aebb1679872ff3a5a0
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -inline < %s -S -o - | FileCheck %s
3 target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
4 target triple = "x86_64-apple-macosx10.15.0"
6 define void @caller1(i8 *%p1, i1 %b) {
7 ; CHECK-LABEL: @caller1(
8 ; CHECK-NEXT:  entry:
9 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i1 [[B:%.*]], true
10 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[SPLIT:%.*]]
11 ; CHECK:       split:
12 ; CHECK-NEXT:    call void @callee(i8* [[P1:%.*]], i32 0, i32 -1)
13 ; CHECK-NEXT:    br label [[EXIT]]
14 ; CHECK:       exit:
15 ; CHECK-NEXT:    ret void
17 entry:
18   %cond = icmp eq i1 %b, true
19   br i1 %cond, label %exit, label %split
21 split:
22   ; This path may be generated from CS splitting and never taken at runtime.
23   call void @callee(i8* %p1, i32 0, i32 -1)
24   br label %exit
26 exit:
27   ret void
30 define  void @callee(i8* %p1, i32 %l1, i32 %l2) {
31 entry:
32   %ext = zext i32 %l2 to i64
33   %vla = alloca float, i64 %ext, align 16
34   call void @extern_call(float* nonnull %vla) #3
35   ret void
39 define void @caller2_below_threshold(i8 *%p1, i1 %b) {
40 ; CHECK-LABEL: @caller2_below_threshold(
41 ; CHECK-NEXT:  entry:
42 ; CHECK-NEXT:    [[VLA_I:%.*]] = alloca float, i64 15000, align 16
43 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i1 [[B:%.*]], true
44 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[SPLIT:%.*]]
45 ; CHECK:       split:
46 ; CHECK-NEXT:    [[SAVEDSTACK:%.*]] = call i8* @llvm.stacksave()
47 ; CHECK-NEXT:    [[TMP0:%.*]] = bitcast float* [[VLA_I]] to i8*
48 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 60000, i8* [[TMP0]])
49 ; CHECK-NEXT:    call void @extern_call(float* nonnull [[VLA_I]]) #3
50 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast float* [[VLA_I]] to i8*
51 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 60000, i8* [[TMP1]])
52 ; CHECK-NEXT:    call void @llvm.stackrestore(i8* [[SAVEDSTACK]])
53 ; CHECK-NEXT:    br label [[EXIT]]
54 ; CHECK:       exit:
55 ; CHECK-NEXT:    ret void
57 entry:
58   %cond = icmp eq i1 %b, true
59   br i1 %cond, label %exit, label %split
61 split:
62   call void @callee(i8* %p1, i32 0, i32 15000)
63   br label %exit
65 exit:
66   ret void
69 define  void @callee2_not_in_entry(i8* %p1, i32 %l1, i32 %l2) {
70 entry:
71   %ext = zext i32 %l2 to i64
72   %c = icmp eq i32 %l1, 42
73   br i1 %c, label %bb2, label %bb3
74 bb2:
75   %vla = alloca float, i64 %ext, align 16
76   call void @extern_call(float* nonnull %vla) #3
77   ret void
78 bb3:
79   ret void
82 define void @caller3_alloca_not_in_entry(i8 *%p1, i1 %b) {
83 ; CHECK-LABEL: @caller3_alloca_not_in_entry(
84 ; CHECK-NEXT:  entry:
85 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i1 [[B:%.*]], true
86 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[SPLIT:%.*]]
87 ; CHECK:       split:
88 ; CHECK-NEXT:    br label [[EXIT]]
89 ; CHECK:       exit:
90 ; CHECK-NEXT:    ret void
92 entry:
93   %cond = icmp eq i1 %b, true
94   br i1 %cond, label %exit, label %split
96 split:
97   call void @callee2_not_in_entry(i8* %p1, i32 0, i32 -1)
98   br label %exit
100 exit:
101   ret void
104 define void @caller4_over_threshold(i8 *%p1, i1 %b, i32 %len) {
105 ; CHECK-LABEL: @caller4_over_threshold(
106 ; CHECK-NEXT:  entry:
107 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i1 [[B:%.*]], true
108 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[SPLIT:%.*]]
109 ; CHECK:       split:
110 ; CHECK-NEXT:    call void @callee(i8* [[P1:%.*]], i32 0, i32 16500)
111 ; CHECK-NEXT:    br label [[EXIT]]
112 ; CHECK:       exit:
113 ; CHECK-NEXT:    ret void
115 entry:
116   %cond = icmp eq i1 %b, true
117   br i1 %cond, label %exit, label %split
119 split:
120   call void @callee(i8* %p1, i32 0, i32 16500)
121   br label %exit
123 exit:
124   ret void
127 declare noalias i8* @malloc(i64)
128 define i8* @stack_allocate(i32 %size) #2 {
129 entry:
130   %cmp = icmp ult i32 %size, 100
131   %conv = zext i32 %size to i64
132   br i1 %cmp, label %if.then, label %if.end
134 if.then:                                          ; preds = %entry
135   %0 = alloca i8, i64 %conv, align 8
136   br label %return
138 if.end:                                           ; preds = %entry
139   %call = tail call i8* @malloc(i64 %conv) #3
140   br label %return
142 return:                                           ; preds = %if.end, %if.then
143   %retval.0 = phi i8* [ %0, %if.then ], [ %call, %if.end ]
144   ret i8* %retval.0
147 define i8* @test_stack_allocate_always(i32 %size) {
148 ; CHECK-LABEL: @test_stack_allocate_always(
149 ; CHECK-NEXT:  entry:
150 ; CHECK-NEXT:    [[SAVEDSTACK:%.*]] = call i8* @llvm.stacksave()
151 ; CHECK-NEXT:    [[CMP_I:%.*]] = icmp ult i32 [[SIZE:%.*]], 100
152 ; CHECK-NEXT:    [[CONV_I:%.*]] = zext i32 [[SIZE]] to i64
153 ; CHECK-NEXT:    br i1 [[CMP_I]], label [[IF_THEN_I:%.*]], label [[IF_END_I:%.*]]
154 ; CHECK:       if.then.i:
155 ; CHECK-NEXT:    [[TMP0:%.*]] = alloca i8, i64 [[CONV_I]], align 8
156 ; CHECK-NEXT:    br label [[STACK_ALLOCATE_EXIT:%.*]]
157 ; CHECK:       if.end.i:
158 ; CHECK-NEXT:    [[CALL_I:%.*]] = tail call i8* @malloc(i64 [[CONV_I]]) #3
159 ; CHECK-NEXT:    br label [[STACK_ALLOCATE_EXIT]]
160 ; CHECK:       stack_allocate.exit:
161 ; CHECK-NEXT:    [[RETVAL_0_I:%.*]] = phi i8* [ [[TMP0]], [[IF_THEN_I]] ], [ [[CALL_I]], [[IF_END_I]] ]
162 ; CHECK-NEXT:    call void @llvm.stackrestore(i8* [[SAVEDSTACK]])
163 ; CHECK-NEXT:    ret i8* [[RETVAL_0_I]]
165 entry:
166   %call = tail call i8* @stack_allocate(i32 %size)
167   ret i8* %call
170 declare void @extern_call(float*)
172 attributes #1 = { argmemonly nounwind willreturn writeonly }
173 attributes #2 = { alwaysinline }
174 attributes #3 = { nounwind }