brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.9 KiB · f13627b Raw
422 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=i686-windows < %s | FileCheck %s3 4declare void @addrof_i1(ptr)5declare void @addrof_i32(ptr)6declare void @addrof_i64(ptr)7declare void @addrof_i128(ptr)8declare void @addrof_i32_x3(ptr, ptr, ptr)9 10define void @simple(i32 %x) {11; CHECK-LABEL: simple:12; CHECK:       # %bb.0: # %entry13; CHECK-NEXT:    leal {{[0-9]+}}(%esp), %eax14; CHECK-NEXT:    pushl %eax15; CHECK-NEXT:    calll _addrof_i3216; CHECK-NEXT:    addl $4, %esp17; CHECK-NEXT:    retl18entry:19  %x.addr = alloca i3220  store i32 %x, ptr %x.addr21  call void @addrof_i32(ptr %x.addr)22  ret void23}24 25; We need to load %x before calling addrof_i32 now because it could mutate %x in26; place.27 28define i32 @use_arg(i32 %x) {29; CHECK-LABEL: use_arg:30; CHECK:       # %bb.0: # %entry31; CHECK-NEXT:    pushl %esi32; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %esi33; CHECK-NEXT:    leal {{[0-9]+}}(%esp), %eax34; CHECK-NEXT:    pushl %eax35; CHECK-NEXT:    calll _addrof_i3236; CHECK-NEXT:    addl $4, %esp37; CHECK-NEXT:    movl %esi, %eax38; CHECK-NEXT:    popl %esi39; CHECK-NEXT:    retl40entry:41  %x.addr = alloca i3242  store i32 %x, ptr %x.addr43  call void @addrof_i32(ptr %x.addr)44  ret i32 %x45}46 47; We won't copy elide for types needing legalization such as i64 or i1.48 49define i64 @split_i64(i64 %x) {50; CHECK-LABEL: split_i64:51; CHECK:       # %bb.0: # %entry52; CHECK-NEXT:    pushl %edi53; CHECK-NEXT:    pushl %esi54; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %esi55; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %edi56; CHECK-NEXT:    leal {{[0-9]+}}(%esp), %eax57; CHECK-NEXT:    pushl %eax58; CHECK-NEXT:    calll _addrof_i6459; CHECK-NEXT:    addl $4, %esp60; CHECK-NEXT:    movl %esi, %eax61; CHECK-NEXT:    movl %edi, %edx62; CHECK-NEXT:    popl %esi63; CHECK-NEXT:    popl %edi64; CHECK-NEXT:    retl65entry:66  %x.addr = alloca i64, align 467  store i64 %x, ptr %x.addr, align 468  call void @addrof_i64(ptr %x.addr)69  ret i64 %x70}71 72define i1 @i1_arg(i1 %x) {73; CHECK-LABEL: i1_arg:74; CHECK:       # %bb.0:75; CHECK-NEXT:    pushl %ebx76; CHECK-NEXT:    pushl %eax77; CHECK-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx78; CHECK-NEXT:    movl %ebx, %eax79; CHECK-NEXT:    andb $1, %al80; CHECK-NEXT:    movb %al, {{[0-9]+}}(%esp)81; CHECK-NEXT:    leal {{[0-9]+}}(%esp), %eax82; CHECK-NEXT:    pushl %eax83; CHECK-NEXT:    calll _addrof_i184; CHECK-NEXT:    addl $4, %esp85; CHECK-NEXT:    movl %ebx, %eax86; CHECK-NEXT:    addl $4, %esp87; CHECK-NEXT:    popl %ebx88; CHECK-NEXT:    retl89  %x.addr = alloca i190  store i1 %x, ptr %x.addr91  call void @addrof_i1(ptr %x.addr)92  ret i1 %x93}94 95; We can't copy elide when an i64 is split between registers and memory in a96; fastcc function.97 98define fastcc i64 @fastcc_split_i64(ptr %p, i64 %x) {99; CHECK-LABEL: fastcc_split_i64:100; CHECK:       # %bb.0: # %entry101; CHECK-NEXT:    pushl %edi102; CHECK-NEXT:    pushl %esi103; CHECK-NEXT:    subl $8, %esp104; CHECK-NEXT:    movl %edx, %esi105; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %edi106; CHECK-NEXT:    movl %edi, {{[0-9]+}}(%esp)107; CHECK-NEXT:    movl %edx, (%esp)108; CHECK-NEXT:    movl %esp, %eax109; CHECK-NEXT:    pushl %eax110; CHECK-NEXT:    calll _addrof_i64111; CHECK-NEXT:    addl $4, %esp112; CHECK-NEXT:    movl %esi, %eax113; CHECK-NEXT:    movl %edi, %edx114; CHECK-NEXT:    addl $8, %esp115; CHECK-NEXT:    popl %esi116; CHECK-NEXT:    popl %edi117; CHECK-NEXT:    retl118entry:119  %x.addr = alloca i64, align 4120  store i64 %x, ptr %x.addr, align 4121  call void @addrof_i64(ptr %x.addr)122  ret i64 %x123}124 125; We can't copy elide when it would reduce the user requested alignment.126 127define void @high_alignment(i32 %x) {128; CHECK-LABEL: high_alignment:129; CHECK:       # %bb.0: # %entry130; CHECK-NEXT:    pushl %ebp131; CHECK-NEXT:    movl %esp, %ebp132; CHECK-NEXT:    andl $-128, %esp133; CHECK-NEXT:    subl $128, %esp134; CHECK-NEXT:    movl 8(%ebp), %eax135; CHECK-NEXT:    movl %eax, (%esp)136; CHECK-NEXT:    movl %esp, %eax137; CHECK-NEXT:    pushl %eax138; CHECK-NEXT:    calll _addrof_i32139; CHECK-NEXT:    addl $4, %esp140; CHECK-NEXT:    movl %ebp, %esp141; CHECK-NEXT:    popl %ebp142; CHECK-NEXT:    retl143entry:144  %x.p = alloca i32, align 128145  store i32 %x, ptr %x.p146  call void @addrof_i32(ptr %x.p)147  ret void148}149 150; We can't copy elide when it would reduce the ABI required alignment.151; FIXME: We should lower the ABI alignment of i64 on Windows, since MSVC152; doesn't guarantee it.153 154define void @abi_alignment(i64 %x) {155; CHECK-LABEL: abi_alignment:156; CHECK:       # %bb.0: # %entry157; CHECK-NEXT:    pushl %ebp158; CHECK-NEXT:    movl %esp, %ebp159; CHECK-NEXT:    andl $-8, %esp160; CHECK-NEXT:    subl $8, %esp161; CHECK-NEXT:    movl 8(%ebp), %eax162; CHECK-NEXT:    movl 12(%ebp), %ecx163; CHECK-NEXT:    movl %ecx, {{[0-9]+}}(%esp)164; CHECK-NEXT:    movl %eax, (%esp)165; CHECK-NEXT:    movl %esp, %eax166; CHECK-NEXT:    pushl %eax167; CHECK-NEXT:    calll _addrof_i64168; CHECK-NEXT:    addl $4, %esp169; CHECK-NEXT:    movl %ebp, %esp170; CHECK-NEXT:    popl %ebp171; CHECK-NEXT:    retl172entry:173  %x.p = alloca i64174  store i64 %x, ptr %x.p175  call void @addrof_i64(ptr %x.p)176  ret void177}178 179; The code we generate for this is unimportant. This is mostly a crash test.180 181define void @split_i128(ptr %sret, i128 %x) {182; CHECK-LABEL: split_i128:183; CHECK:       # %bb.0: # %entry184; CHECK-NEXT:    pushl %ebp185; CHECK-NEXT:    movl %esp, %ebp186; CHECK-NEXT:    pushl %ebx187; CHECK-NEXT:    pushl %edi188; CHECK-NEXT:    pushl %esi189; CHECK-NEXT:    andl $-16, %esp190; CHECK-NEXT:    subl $48, %esp191; CHECK-NEXT:    movl 24(%ebp), %eax192; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill193; CHECK-NEXT:    movl 28(%ebp), %ebx194; CHECK-NEXT:    movl 32(%ebp), %esi195; CHECK-NEXT:    movl 36(%ebp), %edi196; CHECK-NEXT:    movl %edi, {{[0-9]+}}(%esp)197; CHECK-NEXT:    movl %esi, {{[0-9]+}}(%esp)198; CHECK-NEXT:    movl %ebx, {{[0-9]+}}(%esp)199; CHECK-NEXT:    movl %eax, {{[0-9]+}}(%esp)200; CHECK-NEXT:    leal {{[0-9]+}}(%esp), %eax201; CHECK-NEXT:    pushl %eax202; CHECK-NEXT:    calll _addrof_i128203; CHECK-NEXT:    addl $4, %esp204; CHECK-NEXT:    movl 8(%ebp), %eax205; CHECK-NEXT:    movl %edi, 12(%eax)206; CHECK-NEXT:    movl %esi, 8(%eax)207; CHECK-NEXT:    movl %ebx, 4(%eax)208; CHECK-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload209; CHECK-NEXT:    movl %ecx, (%eax)210; CHECK-NEXT:    leal -12(%ebp), %esp211; CHECK-NEXT:    popl %esi212; CHECK-NEXT:    popl %edi213; CHECK-NEXT:    popl %ebx214; CHECK-NEXT:    popl %ebp215; CHECK-NEXT:    retl216entry:217  %x.addr = alloca i128218  store i128 %x, ptr %x.addr219  call void @addrof_i128(ptr %x.addr)220  store i128 %x, ptr %sret221  ret void222}223 224; Check that we load all of x, y, and z before the call.225 226define i32 @three_args(i32 %x, i32 %y, i32 %z) {227; CHECK-LABEL: three_args:228; CHECK:       # %bb.0: # %entry229; CHECK-NEXT:    pushl %esi230; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %esi231; CHECK-NEXT:    addl {{[0-9]+}}(%esp), %esi232; CHECK-NEXT:    addl {{[0-9]+}}(%esp), %esi233; CHECK-NEXT:    leal {{[0-9]+}}(%esp), %eax234; CHECK-NEXT:    leal {{[0-9]+}}(%esp), %ecx235; CHECK-NEXT:    leal {{[0-9]+}}(%esp), %edx236; CHECK-NEXT:    pushl %eax237; CHECK-NEXT:    pushl %ecx238; CHECK-NEXT:    pushl %edx239; CHECK-NEXT:    calll _addrof_i32_x3240; CHECK-NEXT:    addl $12, %esp241; CHECK-NEXT:    movl %esi, %eax242; CHECK-NEXT:    popl %esi243; CHECK-NEXT:    retl244entry:245  %z.addr = alloca i32, align 4246  %y.addr = alloca i32, align 4247  %x.addr = alloca i32, align 4248  store i32 %z, ptr %z.addr, align 4249  store i32 %y, ptr %y.addr, align 4250  store i32 %x, ptr %x.addr, align 4251  call void @addrof_i32_x3(ptr %x.addr, ptr %y.addr, ptr %z.addr)252  %s1 = add i32 %x, %y253  %sum = add i32 %s1, %z254  ret i32 %sum255}256 257define void @two_args_same_alloca(i32 %x, i32 %y) {258; CHECK-LABEL: two_args_same_alloca:259; CHECK:       # %bb.0: # %entry260; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax261; CHECK-NEXT:    movl %eax, {{[0-9]+}}(%esp)262; CHECK-NEXT:    leal {{[0-9]+}}(%esp), %eax263; CHECK-NEXT:    pushl %eax264; CHECK-NEXT:    calll _addrof_i32265; CHECK-NEXT:    addl $4, %esp266; CHECK-NEXT:    retl267entry:268  %x.addr = alloca i32269  store i32 %x, ptr %x.addr270  store i32 %y, ptr %x.addr271  call void @addrof_i32(ptr %x.addr)272  ret void273}274 275define void @avoid_byval(ptr byval(i32) %x) {276; CHECK-LABEL: avoid_byval:277; CHECK:       # %bb.0: # %entry278; CHECK-NEXT:    pushl %eax279; CHECK-NEXT:    leal {{[0-9]+}}(%esp), %eax280; CHECK-NEXT:    movl %eax, (%esp)281; CHECK-NEXT:    pushl %eax282; CHECK-NEXT:    calll _addrof_i32283; CHECK-NEXT:    addl $4, %esp284; CHECK-NEXT:    popl %eax285; CHECK-NEXT:    retl286entry:287  %x.p.p = alloca ptr288  store ptr %x, ptr %x.p.p289  call void @addrof_i32(ptr %x)290  ret void291}292 293define void @avoid_inalloca(ptr inalloca(i32) %x) {294; CHECK-LABEL: avoid_inalloca:295; CHECK:       # %bb.0: # %entry296; CHECK-NEXT:    pushl %eax297; CHECK-NEXT:    leal {{[0-9]+}}(%esp), %eax298; CHECK-NEXT:    movl %eax, (%esp)299; CHECK-NEXT:    pushl %eax300; CHECK-NEXT:    calll _addrof_i32301; CHECK-NEXT:    addl $4, %esp302; CHECK-NEXT:    popl %eax303; CHECK-NEXT:    retl304entry:305  %x.p.p = alloca ptr306  store ptr %x, ptr %x.p.p307  call void @addrof_i32(ptr %x)308  ret void309}310 311define void @avoid_preallocated(ptr preallocated(i32) %x) {312; CHECK-LABEL: avoid_preallocated:313; CHECK:       # %bb.0: # %entry314; CHECK-NEXT:    pushl %eax315; CHECK-NEXT:    leal {{[0-9]+}}(%esp), %eax316; CHECK-NEXT:    movl %eax, (%esp)317; CHECK-NEXT:    pushl %eax318; CHECK-NEXT:    calll _addrof_i32319; CHECK-NEXT:    addl $4, %esp320; CHECK-NEXT:    popl %eax321; CHECK-NEXT:    retl322entry:323  %x.p.p = alloca ptr324  store ptr %x, ptr %x.p.p325  call void @addrof_i32(ptr %x)326  ret void327}328 329; Don't elide the copy when the alloca is escaped with a store.330define void @escape_with_store(i32 %x) {331; CHECK-LABEL: escape_with_store:332; CHECK:       # %bb.0:333; CHECK-NEXT:    subl $8, %esp334; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax335; CHECK-NEXT:    movl %esp, %ecx336; CHECK-NEXT:    movl %ecx, {{[0-9]+}}(%esp)337; CHECK-NEXT:    movl %eax, (%esp)338; CHECK-NEXT:    pushl %ecx339; CHECK-NEXT:    calll _addrof_i32340; CHECK-NEXT:    addl $12, %esp341; CHECK-NEXT:    retl342  %x1 = alloca i32343  %x2 = alloca ptr344  store ptr %x1, ptr %x2345  %x3 = load ptr, ptr %x2346  store i32 0, ptr %x3347  store i32 %x, ptr %x1348  call void @addrof_i32(ptr %x1)349  ret void350}351 352; This test case exposed issues with the use of TokenFactor.353 354define void @sret_and_elide(ptr sret(i32) %sret, i32 %v) {355; CHECK-LABEL: sret_and_elide:356; CHECK:       # %bb.0:357; CHECK-NEXT:    pushl %edi358; CHECK-NEXT:    pushl %esi359; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %esi360; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %edi361; CHECK-NEXT:    leal {{[0-9]+}}(%esp), %eax362; CHECK-NEXT:    pushl %eax363; CHECK-NEXT:    calll _addrof_i32364; CHECK-NEXT:    addl $4, %esp365; CHECK-NEXT:    movl %edi, (%esi)366; CHECK-NEXT:    movl %esi, %eax367; CHECK-NEXT:    popl %esi368; CHECK-NEXT:    popl %edi369; CHECK-NEXT:    retl370  %v.p = alloca i32371  store i32 %v, ptr %v.p372  call void @addrof_i32(ptr %v.p)373  store i32 %v, ptr %sret374  ret void375}376 377define void @avoid_partially_initialized_alloca(i32 %x) {378; CHECK-LABEL: avoid_partially_initialized_alloca:379; CHECK:       # %bb.0:380; CHECK-NEXT:    pushl %ebp381; CHECK-NEXT:    movl %esp, %ebp382; CHECK-NEXT:    andl $-8, %esp383; CHECK-NEXT:    subl $8, %esp384; CHECK-NEXT:    movl 8(%ebp), %eax385; CHECK-NEXT:    movl %eax, (%esp)386; CHECK-NEXT:    movl %esp, %eax387; CHECK-NEXT:    pushl %eax388; CHECK-NEXT:    calll _addrof_i32389; CHECK-NEXT:    addl $4, %esp390; CHECK-NEXT:    movl %ebp, %esp391; CHECK-NEXT:    popl %ebp392; CHECK-NEXT:    retl393  %a = alloca i64394  store i32 %x, ptr %a395  call void @addrof_i32(ptr %a)396  ret void397}398 399; Ensure no copy elision happens as the two i3 values fed into icmp may have400; garbage in the upper bits, a truncation is needed.401 402define i1 @use_i3(i3 %a1, i3 %a2) {403; CHECK-LABEL: use_i3:404; CHECK:       # %bb.0:405; CHECK-NEXT:    pushl %eax406; CHECK-NEXT:    movzbl {{[0-9]+}}(%esp), %eax407; CHECK-NEXT:    andb $7, %al408; CHECK-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx409; CHECK-NEXT:    andb $7, %cl410; CHECK-NEXT:    movb %cl, {{[0-9]+}}(%esp)411; CHECK-NEXT:    cmpb %cl, %al412; CHECK-NEXT:    sete %al413; CHECK-NEXT:    popl %ecx414; CHECK-NEXT:    retl415  %tmp = alloca i3416  store i3 %a2, ptr %tmp417  %val = load i3, ptr %tmp418  %res = icmp eq i3 %a1, %val419  ret i1 %res420}421 422