208 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 52; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=zEC12 -verify-machineinstrs \3; RUN: | FileCheck %s --check-prefix=NOVEC4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z16 -verify-machineinstrs \5; RUN: | FileCheck %s --check-prefix=VECTOR6;7; Tests for strict 16-bit floating point (half).8 9declare half @llvm.experimental.constrained.fadd.f16(half, half, metadata, metadata)10declare double @llvm.experimental.constrained.fadd.f64(double, double, metadata, metadata)11declare half @llvm.experimental.constrained.fmul.f16(half, half, metadata, metadata)12 13; Test register addition.14define half @fun0(half %f1, half %f2) #0 {15; NOVEC-LABEL: fun0:16; NOVEC: # %bb.0:17; NOVEC-NEXT: stmg %r14, %r15, 112(%r15)18; NOVEC-NEXT: .cfi_offset %r14, -4819; NOVEC-NEXT: .cfi_offset %r15, -4020; NOVEC-NEXT: aghi %r15, -17621; NOVEC-NEXT: .cfi_def_cfa_offset 33622; NOVEC-NEXT: std %f8, 168(%r15) # 8-byte Spill23; NOVEC-NEXT: std %f9, 160(%r15) # 8-byte Spill24; NOVEC-NEXT: .cfi_offset %f8, -16825; NOVEC-NEXT: .cfi_offset %f9, -17626; NOVEC-NEXT: ler %f8, %f027; NOVEC-NEXT: ler %f0, %f228; NOVEC-NEXT: brasl %r14, __extendhfsf2@PLT29; NOVEC-NEXT: ler %f9, %f030; NOVEC-NEXT: ler %f0, %f831; NOVEC-NEXT: brasl %r14, __extendhfsf2@PLT32; NOVEC-NEXT: aebr %f0, %f933; NOVEC-NEXT: brasl %r14, __truncsfhf2@PLT34; NOVEC-NEXT: ld %f8, 168(%r15) # 8-byte Reload35; NOVEC-NEXT: ld %f9, 160(%r15) # 8-byte Reload36; NOVEC-NEXT: lmg %r14, %r15, 288(%r15)37; NOVEC-NEXT: br %r1438;39; VECTOR-LABEL: fun0:40; VECTOR: # %bb.0:41; VECTOR-NEXT: stmg %r14, %r15, 112(%r15)42; VECTOR-NEXT: .cfi_offset %r14, -4843; VECTOR-NEXT: .cfi_offset %r15, -4044; VECTOR-NEXT: aghi %r15, -17645; VECTOR-NEXT: .cfi_def_cfa_offset 33646; VECTOR-NEXT: std %f8, 168(%r15) # 8-byte Spill47; VECTOR-NEXT: std %f9, 160(%r15) # 8-byte Spill48; VECTOR-NEXT: .cfi_offset %f8, -16849; VECTOR-NEXT: .cfi_offset %f9, -17650; VECTOR-NEXT: ldr %f8, %f051; VECTOR-NEXT: ldr %f0, %f252; VECTOR-NEXT: brasl %r14, __extendhfsf2@PLT53; VECTOR-NEXT: ldr %f9, %f054; VECTOR-NEXT: ldr %f0, %f855; VECTOR-NEXT: brasl %r14, __extendhfsf2@PLT56; VECTOR-NEXT: aebr %f0, %f957; VECTOR-NEXT: brasl %r14, __truncsfhf2@PLT58; VECTOR-NEXT: ld %f8, 168(%r15) # 8-byte Reload59; VECTOR-NEXT: ld %f9, 160(%r15) # 8-byte Reload60; VECTOR-NEXT: lmg %r14, %r15, 288(%r15)61; VECTOR-NEXT: br %r1462 %res = call half @llvm.experimental.constrained.fadd.f16(63 half %f1, half %f2,64 metadata !"round.dynamic",65 metadata !"fpexcept.strict") #066 ret half %res67}68 69; Test atomic memory accesses and extension/truncation inside a strictfp70; function.71define void @fun1(ptr %Src, ptr %Dst) #0 {72; NOVEC-LABEL: fun1:73; NOVEC: # %bb.0: # %entry74; NOVEC-NEXT: stmg %r13, %r15, 104(%r15)75; NOVEC-NEXT: .cfi_offset %r13, -5676; NOVEC-NEXT: .cfi_offset %r14, -4877; NOVEC-NEXT: .cfi_offset %r15, -4078; NOVEC-NEXT: aghi %r15, -16079; NOVEC-NEXT: .cfi_def_cfa_offset 32080; NOVEC-NEXT: lgh %r0, 0(%r2)81; NOVEC-NEXT: sllg %r0, %r0, 4882; NOVEC-NEXT: lgr %r13, %r383; NOVEC-NEXT: ldgr %f0, %r084; NOVEC-NEXT: # kill: def $f0h killed $f0h killed $f0d85; NOVEC-NEXT: brasl %r14, __extendhfdf2@PLT86; NOVEC-NEXT: adbr %f0, %f087; NOVEC-NEXT: brasl %r14, __truncdfhf2@PLT88; NOVEC-NEXT: # kill: def $f0h killed $f0h def $f0d89; NOVEC-NEXT: lgdr %r0, %f090; NOVEC-NEXT: srlg %r0, %r0, 4891; NOVEC-NEXT: sth %r0, 0(%r13)92; NOVEC-NEXT: bcr 14, %r093; NOVEC-NEXT: lmg %r13, %r15, 264(%r15)94; NOVEC-NEXT: br %r1495;96; VECTOR-LABEL: fun1:97; VECTOR: # %bb.0: # %entry98; VECTOR-NEXT: stmg %r13, %r15, 104(%r15)99; VECTOR-NEXT: .cfi_offset %r13, -56100; VECTOR-NEXT: .cfi_offset %r14, -48101; VECTOR-NEXT: .cfi_offset %r15, -40102; VECTOR-NEXT: aghi %r15, -160103; VECTOR-NEXT: .cfi_def_cfa_offset 320104; VECTOR-NEXT: vlreph %v0, 0(%r2)105; VECTOR-NEXT: lgr %r13, %r3106; VECTOR-NEXT: brasl %r14, __extendhfdf2@PLT107; VECTOR-NEXT: adbr %f0, %f0108; VECTOR-NEXT: brasl %r14, __truncdfhf2@PLT109; VECTOR-NEXT: vsteh %v0, 0(%r13), 0110; VECTOR-NEXT: bcr 14, %r0111; VECTOR-NEXT: lmg %r13, %r15, 264(%r15)112; VECTOR-NEXT: br %r14113entry:114 %Op0 = load atomic half, ptr %Src seq_cst, align 2115 %E0 = fpext half %Op0 to double116 %Add = call double @llvm.experimental.constrained.fadd.f64(117 double %E0, double %E0,118 metadata !"round.dynamic",119 metadata !"fpexcept.strict") #0120 %Res = fptrunc double %Add to half121 store atomic half %Res, ptr %Dst seq_cst, align 2122 ret void123}124 125; Test a chain of half operations which should have each operation surrounded126; by conversions to/from fp32 for proper emulation.127define half @fun2(half %Op0, half %Op1, half %Op2) #0 {128; NOVEC-LABEL: fun2:129; NOVEC: # %bb.0: # %entry130; NOVEC-NEXT: stmg %r14, %r15, 112(%r15)131; NOVEC-NEXT: .cfi_offset %r14, -48132; NOVEC-NEXT: .cfi_offset %r15, -40133; NOVEC-NEXT: aghi %r15, -184134; NOVEC-NEXT: .cfi_def_cfa_offset 344135; NOVEC-NEXT: std %f8, 176(%r15) # 8-byte Spill136; NOVEC-NEXT: std %f9, 168(%r15) # 8-byte Spill137; NOVEC-NEXT: std %f10, 160(%r15) # 8-byte Spill138; NOVEC-NEXT: .cfi_offset %f8, -168139; NOVEC-NEXT: .cfi_offset %f9, -176140; NOVEC-NEXT: .cfi_offset %f10, -184141; NOVEC-NEXT: ler %f9, %f0142; NOVEC-NEXT: ler %f0, %f2143; NOVEC-NEXT: ler %f8, %f4144; NOVEC-NEXT: brasl %r14, __extendhfsf2@PLT145; NOVEC-NEXT: ler %f10, %f0146; NOVEC-NEXT: ler %f0, %f9147; NOVEC-NEXT: brasl %r14, __extendhfsf2@PLT148; NOVEC-NEXT: meebr %f0, %f10149; NOVEC-NEXT: brasl %r14, __truncsfhf2@PLT150; NOVEC-NEXT: brasl %r14, __extendhfsf2@PLT151; NOVEC-NEXT: ler %f9, %f0152; NOVEC-NEXT: ler %f0, %f8153; NOVEC-NEXT: brasl %r14, __extendhfsf2@PLT154; NOVEC-NEXT: meebr %f0, %f9155; NOVEC-NEXT: brasl %r14, __truncsfhf2@PLT156; NOVEC-NEXT: ld %f8, 176(%r15) # 8-byte Reload157; NOVEC-NEXT: ld %f9, 168(%r15) # 8-byte Reload158; NOVEC-NEXT: ld %f10, 160(%r15) # 8-byte Reload159; NOVEC-NEXT: lmg %r14, %r15, 296(%r15)160; NOVEC-NEXT: br %r14161;162; VECTOR-LABEL: fun2:163; VECTOR: # %bb.0: # %entry164; VECTOR-NEXT: stmg %r14, %r15, 112(%r15)165; VECTOR-NEXT: .cfi_offset %r14, -48166; VECTOR-NEXT: .cfi_offset %r15, -40167; VECTOR-NEXT: aghi %r15, -184168; VECTOR-NEXT: .cfi_def_cfa_offset 344169; VECTOR-NEXT: std %f8, 176(%r15) # 8-byte Spill170; VECTOR-NEXT: std %f9, 168(%r15) # 8-byte Spill171; VECTOR-NEXT: std %f10, 160(%r15) # 8-byte Spill172; VECTOR-NEXT: .cfi_offset %f8, -168173; VECTOR-NEXT: .cfi_offset %f9, -176174; VECTOR-NEXT: .cfi_offset %f10, -184175; VECTOR-NEXT: ldr %f9, %f0176; VECTOR-NEXT: ldr %f0, %f2177; VECTOR-NEXT: ldr %f8, %f4178; VECTOR-NEXT: brasl %r14, __extendhfsf2@PLT179; VECTOR-NEXT: ldr %f10, %f0180; VECTOR-NEXT: ldr %f0, %f9181; VECTOR-NEXT: brasl %r14, __extendhfsf2@PLT182; VECTOR-NEXT: meebr %f0, %f10183; VECTOR-NEXT: brasl %r14, __truncsfhf2@PLT184; VECTOR-NEXT: brasl %r14, __extendhfsf2@PLT185; VECTOR-NEXT: ldr %f9, %f0186; VECTOR-NEXT: ldr %f0, %f8187; VECTOR-NEXT: brasl %r14, __extendhfsf2@PLT188; VECTOR-NEXT: wfmsb %f0, %f9, %f0189; VECTOR-NEXT: brasl %r14, __truncsfhf2@PLT190; VECTOR-NEXT: ld %f8, 176(%r15) # 8-byte Reload191; VECTOR-NEXT: ld %f9, 168(%r15) # 8-byte Reload192; VECTOR-NEXT: ld %f10, 160(%r15) # 8-byte Reload193; VECTOR-NEXT: lmg %r14, %r15, 296(%r15)194; VECTOR-NEXT: br %r14195entry:196 %A0 = call half @llvm.experimental.constrained.fmul.f16(197 half %Op0, half %Op1,198 metadata !"round.dynamic",199 metadata !"fpexcept.strict") #0200 %Res = call half @llvm.experimental.constrained.fmul.f16(201 half %A0, half %Op2,202 metadata !"round.dynamic",203 metadata !"fpexcept.strict") #0204 ret half %Res205}206 207attributes #0 = { strictfp }208