318 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -x86-use-vzeroupper -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefixes=ALL,VZ3; RUN: llc < %s -x86-use-vzeroupper -mtriple=x86_64-unknown-unknown -mattr=+avx512f | FileCheck %s --check-prefixes=ALL,VZ4; RUN: llc < %s -x86-use-vzeroupper -mtriple=x86_64-unknown-unknown -mattr=+avx,-vzeroupper | FileCheck %s --check-prefixes=ALL,DISABLE-VZ5; RUN: llc < %s -x86-use-vzeroupper -mtriple=x86_64-unknown-unknown -mcpu=bdver2 | FileCheck %s --check-prefixes=ALL,BDVER26; RUN: llc < %s -x86-use-vzeroupper -mtriple=x86_64-unknown-unknown -mcpu=btver2 | FileCheck %s --check-prefixes=ALL,BTVER27 8declare dso_local i32 @foo()9declare dso_local <4 x float> @do_sse(<4 x float>)10declare dso_local <8 x float> @do_avx(<8 x float>)11declare dso_local <4 x float> @llvm.x86.avx.vextractf128.ps.256(<8 x float>, i8) nounwind readnone12@x = common dso_local global <4 x float> zeroinitializer, align 1613@g = common dso_local global <8 x float> zeroinitializer, align 3214 15;; Basic checking - don't emit any vzeroupper instruction16 17define <4 x float> @test00(<4 x float> %a, <4 x float> %b) nounwind {18; ALL-LABEL: test00:19; ALL: # %bb.0:20; ALL-NEXT: pushq %rax21; ALL-NEXT: vaddps %xmm1, %xmm0, %xmm022; ALL-NEXT: callq do_sse23; ALL-NEXT: popq %rax24; ALL-NEXT: retq25 %add.i = fadd <4 x float> %a, %b26 %call3 = call <4 x float> @do_sse(<4 x float> %add.i) nounwind27 ret <4 x float> %call328}29 30;; Check parameter 256-bit parameter passing31 32define <8 x float> @test01(<4 x float> %a, <4 x float> %b, <8 x float> %c) nounwind {33; VZ-LABEL: test01:34; VZ: # %bb.0:35; VZ-NEXT: subq $40, %rsp36; VZ-NEXT: vmovups %ymm2, (%rsp) # 32-byte Spill37; VZ-NEXT: vmovaps x(%rip), %xmm038; VZ-NEXT: vzeroupper39; VZ-NEXT: callq do_sse40; VZ-NEXT: vmovaps %xmm0, x(%rip)41; VZ-NEXT: callq do_sse42; VZ-NEXT: vmovaps %xmm0, x(%rip)43; VZ-NEXT: vmovups (%rsp), %ymm0 # 32-byte Reload44; VZ-NEXT: addq $40, %rsp45; VZ-NEXT: retq46;47; DISABLE-VZ-LABEL: test01:48; DISABLE-VZ: # %bb.0:49; DISABLE-VZ-NEXT: subq $40, %rsp50; DISABLE-VZ-NEXT: vmovups %ymm2, (%rsp) # 32-byte Spill51; DISABLE-VZ-NEXT: vmovaps x(%rip), %xmm052; DISABLE-VZ-NEXT: callq do_sse53; DISABLE-VZ-NEXT: vmovaps %xmm0, x(%rip)54; DISABLE-VZ-NEXT: callq do_sse55; DISABLE-VZ-NEXT: vmovaps %xmm0, x(%rip)56; DISABLE-VZ-NEXT: vmovups (%rsp), %ymm0 # 32-byte Reload57; DISABLE-VZ-NEXT: addq $40, %rsp58; DISABLE-VZ-NEXT: retq59;60; BDVER2-LABEL: test01:61; BDVER2: # %bb.0:62; BDVER2-NEXT: subq $40, %rsp63; BDVER2-NEXT: vmovaps x(%rip), %xmm064; BDVER2-NEXT: vmovups %ymm2, (%rsp) # 32-byte Spill65; BDVER2-NEXT: vzeroupper66; BDVER2-NEXT: callq do_sse67; BDVER2-NEXT: vmovaps %xmm0, x(%rip)68; BDVER2-NEXT: callq do_sse69; BDVER2-NEXT: vmovaps %xmm0, x(%rip)70; BDVER2-NEXT: vmovups (%rsp), %ymm0 # 32-byte Reload71; BDVER2-NEXT: addq $40, %rsp72; BDVER2-NEXT: retq73;74; BTVER2-LABEL: test01:75; BTVER2: # %bb.0:76; BTVER2-NEXT: subq $40, %rsp77; BTVER2-NEXT: vmovaps x(%rip), %xmm078; BTVER2-NEXT: vmovups %ymm2, (%rsp) # 32-byte Spill79; BTVER2-NEXT: callq do_sse80; BTVER2-NEXT: vmovaps %xmm0, x(%rip)81; BTVER2-NEXT: callq do_sse82; BTVER2-NEXT: vmovaps %xmm0, x(%rip)83; BTVER2-NEXT: vmovups (%rsp), %ymm0 # 32-byte Reload84; BTVER2-NEXT: addq $40, %rsp85; BTVER2-NEXT: retq86 %tmp = load <4 x float>, ptr @x, align 1687 %call = tail call <4 x float> @do_sse(<4 x float> %tmp) nounwind88 store <4 x float> %call, ptr @x, align 1689 %call2 = tail call <4 x float> @do_sse(<4 x float> %call) nounwind90 store <4 x float> %call2, ptr @x, align 1691 ret <8 x float> %c92}93 94;; Check that vzeroupper is emitted for tail calls.95 96define <4 x float> @test02(<8 x float> %a, <8 x float> %b) nounwind {97; VZ-LABEL: test02:98; VZ: # %bb.0:99; VZ-NEXT: vaddps %xmm1, %xmm0, %xmm0100; VZ-NEXT: vzeroupper101; VZ-NEXT: jmp do_sse # TAILCALL102;103; DISABLE-VZ-LABEL: test02:104; DISABLE-VZ: # %bb.0:105; DISABLE-VZ-NEXT: vaddps %xmm1, %xmm0, %xmm0106; DISABLE-VZ-NEXT: jmp do_sse # TAILCALL107;108; BDVER2-LABEL: test02:109; BDVER2: # %bb.0:110; BDVER2-NEXT: vaddps %xmm1, %xmm0, %xmm0111; BDVER2-NEXT: vzeroupper112; BDVER2-NEXT: jmp do_sse # TAILCALL113;114; BTVER2-LABEL: test02:115; BTVER2: # %bb.0:116; BTVER2-NEXT: vaddps %xmm1, %xmm0, %xmm0117; BTVER2-NEXT: jmp do_sse # TAILCALL118 %add.i = fadd <8 x float> %a, %b119 %add.low = call <4 x float> @llvm.x86.avx.vextractf128.ps.256(<8 x float> %add.i, i8 0)120 %call3 = tail call <4 x float> @do_sse(<4 x float> %add.low) nounwind121 ret <4 x float> %call3122}123 124;; Test the pass convergence and also that vzeroupper is only issued when necessary,125;; for this function it should be only once126 127define <4 x float> @test03(<4 x float> %a, <4 x float> %b) nounwind {128; VZ-LABEL: test03:129; VZ: # %bb.0: # %entry130; VZ-NEXT: pushq %rbx131; VZ-NEXT: subq $16, %rsp132; VZ-NEXT: vaddps %xmm1, %xmm0, %xmm0133; VZ-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill134; VZ-NEXT: .p2align 4135; VZ-NEXT: .LBB3_1: # %while.cond136; VZ-NEXT: # =>This Inner Loop Header: Depth=1137; VZ-NEXT: callq foo138; VZ-NEXT: testl %eax, %eax139; VZ-NEXT: jne .LBB3_1140; VZ-NEXT: # %bb.2: # %for.body.preheader141; VZ-NEXT: movl $4, %ebx142; VZ-NEXT: vmovaps (%rsp), %xmm0 # 16-byte Reload143; VZ-NEXT: .p2align 4144; VZ-NEXT: .LBB3_3: # %for.body145; VZ-NEXT: # =>This Inner Loop Header: Depth=1146; VZ-NEXT: callq do_sse147; VZ-NEXT: callq do_sse148; VZ-NEXT: vmovaps g+16(%rip), %xmm0149; VZ-NEXT: callq do_sse150; VZ-NEXT: decl %ebx151; VZ-NEXT: jne .LBB3_3152; VZ-NEXT: # %bb.4: # %for.end153; VZ-NEXT: addq $16, %rsp154; VZ-NEXT: popq %rbx155; VZ-NEXT: retq156;157; DISABLE-VZ-LABEL: test03:158; DISABLE-VZ: # %bb.0: # %entry159; DISABLE-VZ-NEXT: pushq %rbx160; DISABLE-VZ-NEXT: subq $16, %rsp161; DISABLE-VZ-NEXT: vaddps %xmm1, %xmm0, %xmm0162; DISABLE-VZ-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill163; DISABLE-VZ-NEXT: .p2align 4164; DISABLE-VZ-NEXT: .LBB3_1: # %while.cond165; DISABLE-VZ-NEXT: # =>This Inner Loop Header: Depth=1166; DISABLE-VZ-NEXT: callq foo167; DISABLE-VZ-NEXT: testl %eax, %eax168; DISABLE-VZ-NEXT: jne .LBB3_1169; DISABLE-VZ-NEXT: # %bb.2: # %for.body.preheader170; DISABLE-VZ-NEXT: movl $4, %ebx171; DISABLE-VZ-NEXT: vmovaps (%rsp), %xmm0 # 16-byte Reload172; DISABLE-VZ-NEXT: .p2align 4173; DISABLE-VZ-NEXT: .LBB3_3: # %for.body174; DISABLE-VZ-NEXT: # =>This Inner Loop Header: Depth=1175; DISABLE-VZ-NEXT: callq do_sse176; DISABLE-VZ-NEXT: callq do_sse177; DISABLE-VZ-NEXT: vmovaps g+16(%rip), %xmm0178; DISABLE-VZ-NEXT: callq do_sse179; DISABLE-VZ-NEXT: decl %ebx180; DISABLE-VZ-NEXT: jne .LBB3_3181; DISABLE-VZ-NEXT: # %bb.4: # %for.end182; DISABLE-VZ-NEXT: addq $16, %rsp183; DISABLE-VZ-NEXT: popq %rbx184; DISABLE-VZ-NEXT: retq185;186; BDVER2-LABEL: test03:187; BDVER2: # %bb.0: # %entry188; BDVER2-NEXT: pushq %rbx189; BDVER2-NEXT: subq $16, %rsp190; BDVER2-NEXT: vaddps %xmm1, %xmm0, %xmm0191; BDVER2-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill192; BDVER2-NEXT: .p2align 4193; BDVER2-NEXT: .LBB3_1: # %while.cond194; BDVER2-NEXT: # =>This Inner Loop Header: Depth=1195; BDVER2-NEXT: callq foo196; BDVER2-NEXT: testl %eax, %eax197; BDVER2-NEXT: jne .LBB3_1198; BDVER2-NEXT: # %bb.2: # %for.body.preheader199; BDVER2-NEXT: vmovaps (%rsp), %xmm0 # 16-byte Reload200; BDVER2-NEXT: movl $4, %ebx201; BDVER2-NEXT: .p2align 4202; BDVER2-NEXT: .LBB3_3: # %for.body203; BDVER2-NEXT: # =>This Inner Loop Header: Depth=1204; BDVER2-NEXT: callq do_sse205; BDVER2-NEXT: callq do_sse206; BDVER2-NEXT: vmovaps g+16(%rip), %xmm0207; BDVER2-NEXT: callq do_sse208; BDVER2-NEXT: decl %ebx209; BDVER2-NEXT: jne .LBB3_3210; BDVER2-NEXT: # %bb.4: # %for.end211; BDVER2-NEXT: addq $16, %rsp212; BDVER2-NEXT: popq %rbx213; BDVER2-NEXT: retq214;215; BTVER2-LABEL: test03:216; BTVER2: # %bb.0: # %entry217; BTVER2-NEXT: pushq %rbx218; BTVER2-NEXT: subq $16, %rsp219; BTVER2-NEXT: vaddps %xmm1, %xmm0, %xmm0220; BTVER2-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill221; BTVER2-NEXT: .p2align 4222; BTVER2-NEXT: .LBB3_1: # %while.cond223; BTVER2-NEXT: # =>This Inner Loop Header: Depth=1224; BTVER2-NEXT: callq foo225; BTVER2-NEXT: testl %eax, %eax226; BTVER2-NEXT: jne .LBB3_1227; BTVER2-NEXT: # %bb.2: # %for.body.preheader228; BTVER2-NEXT: vmovaps (%rsp), %xmm0 # 16-byte Reload229; BTVER2-NEXT: movl $4, %ebx230; BTVER2-NEXT: .p2align 4231; BTVER2-NEXT: .LBB3_3: # %for.body232; BTVER2-NEXT: # =>This Inner Loop Header: Depth=1233; BTVER2-NEXT: callq do_sse234; BTVER2-NEXT: callq do_sse235; BTVER2-NEXT: vmovaps g+16(%rip), %xmm0236; BTVER2-NEXT: callq do_sse237; BTVER2-NEXT: decl %ebx238; BTVER2-NEXT: jne .LBB3_3239; BTVER2-NEXT: # %bb.4: # %for.end240; BTVER2-NEXT: addq $16, %rsp241; BTVER2-NEXT: popq %rbx242; BTVER2-NEXT: retq243entry:244 %add.i = fadd <4 x float> %a, %b245 br label %while.cond246 247while.cond:248 %call = tail call i32 @foo()249 %tobool = icmp eq i32 %call, 0250 br i1 %tobool, label %for.body, label %while.cond251 252for.body:253 %i.018 = phi i32 [ 0, %while.cond ], [ %1, %for.body ]254 %c.017 = phi <4 x float> [ %add.i, %while.cond ], [ %call14, %for.body ]255 %call5 = tail call <4 x float> @do_sse(<4 x float> %c.017) nounwind256 %call7 = tail call <4 x float> @do_sse(<4 x float> %call5) nounwind257 %tmp11 = load <8 x float>, ptr @g, align 32258 %0 = tail call <4 x float> @llvm.x86.avx.vextractf128.ps.256(<8 x float> %tmp11, i8 1) nounwind259 %call14 = tail call <4 x float> @do_sse(<4 x float> %0) nounwind260 %1 = add nsw i32 %i.018, 1261 %exitcond = icmp eq i32 %1, 4262 br i1 %exitcond, label %for.end, label %for.body263 264for.end:265 ret <4 x float> %call14266}267 268;; Check that we also perform vzeroupper when we return from a function.269 270define <4 x float> @test04(<4 x float> %a, <4 x float> %b) nounwind {271; VZ-LABEL: test04:272; VZ: # %bb.0:273; VZ-NEXT: pushq %rax274; VZ-NEXT: # kill: def $xmm0 killed $xmm0 def $ymm0275; VZ-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0276; VZ-NEXT: callq do_avx277; VZ-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0278; VZ-NEXT: popq %rax279; VZ-NEXT: vzeroupper280; VZ-NEXT: retq281;282; DISABLE-VZ-LABEL: test04:283; DISABLE-VZ: # %bb.0:284; DISABLE-VZ-NEXT: pushq %rax285; DISABLE-VZ-NEXT: # kill: def $xmm0 killed $xmm0 def $ymm0286; DISABLE-VZ-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0287; DISABLE-VZ-NEXT: callq do_avx288; DISABLE-VZ-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0289; DISABLE-VZ-NEXT: popq %rax290; DISABLE-VZ-NEXT: retq291;292; BDVER2-LABEL: test04:293; BDVER2: # %bb.0:294; BDVER2-NEXT: pushq %rax295; BDVER2-NEXT: # kill: def $xmm0 killed $xmm0 def $ymm0296; BDVER2-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0297; BDVER2-NEXT: callq do_avx298; BDVER2-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0299; BDVER2-NEXT: popq %rax300; BDVER2-NEXT: vzeroupper301; BDVER2-NEXT: retq302;303; BTVER2-LABEL: test04:304; BTVER2: # %bb.0:305; BTVER2-NEXT: pushq %rax306; BTVER2-NEXT: # kill: def $xmm0 killed $xmm0 def $ymm0307; BTVER2-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0308; BTVER2-NEXT: callq do_avx309; BTVER2-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0310; BTVER2-NEXT: popq %rax311; BTVER2-NEXT: retq312 %shuf = shufflevector <4 x float> %a, <4 x float> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>313 %call = call <8 x float> @do_avx(<8 x float> %shuf) nounwind314 %shuf2 = shufflevector <8 x float> %call, <8 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>315 ret <4 x float> %shuf2316}317 318