1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S -data-layout="E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" | FileCheck %s -check-prefixes=ALL,CHECK 3; RUN: opt < %s -passes=instcombine -S -data-layout="E-p:32:32:32-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" | FileCheck %s -check-prefixes=ALL,P32 4; RUN: opt < %s -passes=instcombine -S | FileCheck %s -check-prefixes=ALL,NODL 5 6declare void @use(...) 7 8@int = global i32 zeroinitializer 9 10; Zero byte allocas should be merged if they can't be deleted. 11define void @test() { 12; CHECK-LABEL: @test( 13; CHECK-NEXT: [[X:%.*]] = alloca [0 x i32], align 4 14; CHECK-NEXT: call void (...) @use(ptr nonnull [[X]]) 15; CHECK-NEXT: call void (...) @use(ptr nonnull [[X]]) 16; CHECK-NEXT: call void (...) @use(ptr nonnull [[X]]) 17; CHECK-NEXT: call void (...) @use(ptr nonnull [[X]]) 18; CHECK-NEXT: ret void 19; 20; P32-LABEL: @test( 21; P32-NEXT: [[X:%.*]] = alloca [0 x i32], align 4 22; P32-NEXT: call void (...) @use(ptr nonnull [[X]]) 23; P32-NEXT: call void (...) @use(ptr nonnull [[X]]) 24; P32-NEXT: call void (...) @use(ptr nonnull [[X]]) 25; P32-NEXT: call void (...) @use(ptr nonnull [[X]]) 26; P32-NEXT: ret void 27; 28; NODL-LABEL: @test( 29; NODL-NEXT: [[X:%.*]] = alloca [0 x i32], align 8 30; NODL-NEXT: call void (...) @use(ptr nonnull [[X]]) 31; NODL-NEXT: call void (...) @use(ptr nonnull [[X]]) 32; NODL-NEXT: call void (...) @use(ptr nonnull [[X]]) 33; NODL-NEXT: call void (...) @use(ptr nonnull [[X]]) 34; NODL-NEXT: ret void 35; 36 %X = alloca [0 x i32] ; <ptr> [#uses=1] 37 call void (...) @use( ptr %X ) 38 %Y = alloca i32, i32 0 ; <ptr> [#uses=1] 39 call void (...) @use( ptr %Y ) 40 %Z = alloca { } ; <ptr> [#uses=1] 41 call void (...) @use( ptr %Z ) 42 %size = load i32, ptr @int 43 %A = alloca {{}}, i32 %size 44 call void (...) @use( ptr %A ) 45 ret void 46} 47 48; Zero byte allocas should be deleted. 49define void @test2() { 50; ALL-LABEL: @test2( 51; ALL-NEXT: ret void 52; 53 %A = alloca i32 ; <ptr> [#uses=1] 54 store i32 123, ptr %A 55 ret void 56} 57 58; Zero byte allocas should be deleted. 59define void @test3() { 60; ALL-LABEL: @test3( 61; ALL-NEXT: ret void 62; 63 %A = alloca { i32 } ; <ptr> [#uses=1] 64 %B = getelementptr { i32 }, ptr %A, i32 0, i32 0 ; <ptr> [#uses=1] 65 store i32 123, ptr %B 66 ret void 67} 68 69define ptr @test4(i32 %n) { 70; CHECK-LABEL: @test4( 71; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[N:%.*]] to i64 72; CHECK-NEXT: [[A:%.*]] = alloca i32, i64 [[TMP1]], align 4 73; CHECK-NEXT: ret ptr [[A]] 74; 75; P32-LABEL: @test4( 76; P32-NEXT: [[A:%.*]] = alloca i32, i32 [[N:%.*]], align 4 77; P32-NEXT: ret ptr [[A]] 78; 79; NODL-LABEL: @test4( 80; NODL-NEXT: [[TMP1:%.*]] = zext i32 [[N:%.*]] to i64 81; NODL-NEXT: [[A:%.*]] = alloca i32, i64 [[TMP1]], align 4 82; NODL-NEXT: ret ptr [[A]] 83; 84 %A = alloca i32, i32 %n 85 ret ptr %A 86} 87 88; Allocas which are only used by GEPs, bitcasts, addrspacecasts, and stores 89; (transitively) should be deleted. 90define void @test5() { 91; ALL-LABEL: @test5( 92; ALL-NEXT: entry: 93; ALL-NEXT: ret void 94; 95 96entry: 97 %a = alloca { i32 } 98 %b = alloca ptr 99 %c = alloca i32 100 store i32 123, ptr %a 101 store ptr %a, ptr %b 102 store i32 123, ptr %b 103 store atomic i32 2, ptr %a unordered, align 4 104 store atomic i32 3, ptr %a release, align 4 105 store atomic i32 4, ptr %a seq_cst, align 4 106 %c.1 = addrspacecast ptr %c to ptr addrspace(1) 107 store i32 123, ptr addrspace(1) %c.1 108 ret void 109} 110 111declare void @f(ptr %p) 112 113; Check that we don't delete allocas in some erroneous cases. 114define void @test6() { 115; CHECK-LABEL: @test6( 116; CHECK-NEXT: entry: 117; CHECK-NEXT: [[A:%.*]] = alloca { i32 }, align 4 118; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4 119; CHECK-NEXT: store volatile i32 123, ptr [[A]], align 4 120; CHECK-NEXT: tail call void @f(ptr nonnull [[B]]) 121; CHECK-NEXT: ret void 122; 123; P32-LABEL: @test6( 124; P32-NEXT: entry: 125; P32-NEXT: [[A:%.*]] = alloca { i32 }, align 4 126; P32-NEXT: [[B:%.*]] = alloca i32, align 4 127; P32-NEXT: store volatile i32 123, ptr [[A]], align 4 128; P32-NEXT: tail call void @f(ptr nonnull [[B]]) 129; P32-NEXT: ret void 130; 131; NODL-LABEL: @test6( 132; NODL-NEXT: entry: 133; NODL-NEXT: [[A:%.*]] = alloca { i32 }, align 8 134; NODL-NEXT: [[B:%.*]] = alloca i32, align 4 135; NODL-NEXT: store volatile i32 123, ptr [[A]], align 4 136; NODL-NEXT: tail call void @f(ptr nonnull [[B]]) 137; NODL-NEXT: ret void 138; 139 140entry: 141 %a = alloca { i32 } 142 %b = alloca i32 143 store volatile i32 123, ptr %a 144 tail call void @f(ptr %b) 145 ret void 146} 147 148; PR14371 149%opaque_type = type opaque 150%real_type = type { { i32, ptr } } 151 152@opaque_global = external constant %opaque_type, align 4 153 154define void @test7() { 155; ALL-LABEL: @test7( 156; ALL-NEXT: entry: 157; ALL-NEXT: ret void 158; 159entry: 160 %0 = alloca %real_type, align 4 161 call void @llvm.memcpy.p0.p0.i32(ptr %0, ptr @opaque_global, i32 8, i1 false) 162 ret void 163} 164 165declare void @llvm.memcpy.p0.p0.i32(ptr nocapture, ptr nocapture, i32, i1) nounwind 166 167 168; Check that the GEP indices use the pointer size, or 64 if unknown 169define void @test8() { 170; ALL-LABEL: @test8( 171; ALL-NEXT: [[X1:%.*]] = alloca [100 x i32], align 4 172; ALL-NEXT: call void (...) @use(ptr nonnull [[X1]]) 173; ALL-NEXT: ret void 174; 175 176 177 %x = alloca i32, i32 100 178 call void (...) @use(ptr %x) 179 ret void 180} 181 182; PR19569 183%struct_type = type { i32, i32 } 184declare void @test9_aux(ptr inalloca(<{ %struct_type }>)) 185declare ptr @llvm.stacksave() 186declare void @llvm.stackrestore(ptr) 187 188define void @test9(ptr %a) { 189; CHECK-LABEL: @test9( 190; CHECK-NEXT: entry: 191; CHECK-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_TYPE:%.*]] }>, align 1 192; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[A:%.*]], align 4 193; CHECK-NEXT: store i64 [[TMP0]], ptr [[ARGMEM]], align 4 194; CHECK-NEXT: call void @test9_aux(ptr nonnull inalloca(<{ [[STRUCT_TYPE]] }>) [[ARGMEM]]) 195; CHECK-NEXT: ret void 196; 197; P32-LABEL: @test9( 198; P32-NEXT: entry: 199; P32-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_TYPE:%.*]] }>, align 1 200; P32-NEXT: [[TMP0:%.*]] = load i64, ptr [[A:%.*]], align 4 201; P32-NEXT: store i64 [[TMP0]], ptr [[ARGMEM]], align 4 202; P32-NEXT: call void @test9_aux(ptr nonnull inalloca(<{ [[STRUCT_TYPE]] }>) [[ARGMEM]]) 203; P32-NEXT: ret void 204; 205; NODL-LABEL: @test9( 206; NODL-NEXT: entry: 207; NODL-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_TYPE:%.*]] }>, align 8 208; NODL-NEXT: [[TMP0:%.*]] = load i64, ptr [[A:%.*]], align 4 209; NODL-NEXT: store i64 [[TMP0]], ptr [[ARGMEM]], align 8 210; NODL-NEXT: call void @test9_aux(ptr nonnull inalloca(<{ [[STRUCT_TYPE]] }>) [[ARGMEM]]) 211; NODL-NEXT: ret void 212; 213entry: 214 %inalloca.save = call ptr @llvm.stacksave() 215 %argmem = alloca inalloca <{ %struct_type }> 216 call void @llvm.memcpy.p0.p0.i32(ptr align 4 %argmem, ptr align 4 %a, i32 8, i1 false) 217 call void @test9_aux(ptr inalloca(<{ %struct_type }>) %argmem) 218 call void @llvm.stackrestore(ptr %inalloca.save) 219 ret void 220} 221 222define void @test10() { 223; ALL-LABEL: @test10( 224; ALL-NEXT: entry: 225; ALL-NEXT: [[V32:%.*]] = alloca i1, align 8 226; ALL-NEXT: [[V64:%.*]] = alloca i1, align 8 227; ALL-NEXT: [[V33:%.*]] = alloca i1, align 8 228; ALL-NEXT: call void (...) @use(ptr nonnull [[V32]], ptr nonnull [[V64]], ptr nonnull [[V33]]) 229; ALL-NEXT: ret void 230; 231entry: 232 %v32 = alloca i1, align 8 233 %v64 = alloca i1, i64 1, align 8 234 %v33 = alloca i1, i33 1, align 8 235 call void (...) @use(ptr %v32, ptr %v64, ptr %v33) 236 ret void 237} 238 239define void @test11() { 240; ALL-LABEL: @test11( 241; ALL-NEXT: entry: 242; ALL-NEXT: [[Y:%.*]] = alloca i32, align 4 243; ALL-NEXT: call void (...) @use(ptr nonnull @int) [ "blah"(ptr [[Y]]) ] 244; ALL-NEXT: ret void 245; 246entry: 247 %y = alloca i32 248 call void (...) @use(ptr nonnull @int) [ "blah"(ptr %y) ] 249 ret void 250} 251 252define void @test_inalloca_with_element_count(ptr %a) { 253; ALL-LABEL: @test_inalloca_with_element_count( 254; ALL-NEXT: [[ALLOCA1:%.*]] = alloca inalloca [10 x %struct_type], align 4 255; ALL-NEXT: call void @test9_aux(ptr nonnull inalloca([[STRUCT_TYPE:%.*]]) [[ALLOCA1]]) 256; ALL-NEXT: ret void 257; 258 %alloca = alloca inalloca %struct_type, i32 10, align 4 259 call void @test9_aux(ptr inalloca(%struct_type) %alloca) 260 ret void 261} 262