535 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc %s -o - -mtriple=avr | FileCheck %s3 4; Tests for various operations on half precison float. Much of the test is5; copied from test/CodeGen/X86/half.ll.6 7define void @store(half %x, ptr %p) nounwind {8; CHECK-LABEL: store:9; CHECK: ; %bb.0:10; CHECK-NEXT: mov r30, r2211; CHECK-NEXT: mov r31, r2312; CHECK-NEXT: std Z+1, r2513; CHECK-NEXT: st Z, r2414; CHECK-NEXT: ret15 store half %x, ptr %p16 ret void17}18 19define half @return(ptr %p) nounwind {20; CHECK-LABEL: return:21; CHECK: ; %bb.0:22; CHECK-NEXT: mov r30, r2423; CHECK-NEXT: mov r31, r2524; CHECK-NEXT: ld r24, Z25; CHECK-NEXT: ldd r25, Z+126; CHECK-NEXT: ret27 %r = load half, ptr %p28 ret half %r29}30 31define dso_local double @loadd(ptr nocapture readonly %a) local_unnamed_addr nounwind {32; CHECK-LABEL: loadd:33; CHECK: ; %bb.0: ; %entry34; CHECK-NEXT: mov r30, r2435; CHECK-NEXT: mov r31, r2536; CHECK-NEXT: ldd r24, Z+237; CHECK-NEXT: ldd r25, Z+338; CHECK-NEXT: rcall __extendhfsf239; CHECK-NEXT: rcall __extendsfdf240; CHECK-NEXT: ret41entry:42 %arrayidx = getelementptr inbounds i16, ptr %a, i64 143 %0 = load i16, ptr %arrayidx, align 244 %1 = tail call double @llvm.convert.from.fp16.f64(i16 %0)45 ret double %146}47 48define dso_local float @loadf(ptr nocapture readonly %a) local_unnamed_addr nounwind {49; CHECK-LABEL: loadf:50; CHECK: ; %bb.0: ; %entry51; CHECK-NEXT: mov r30, r2452; CHECK-NEXT: mov r31, r2553; CHECK-NEXT: ldd r24, Z+254; CHECK-NEXT: ldd r25, Z+355; CHECK-NEXT: rcall __extendhfsf256; CHECK-NEXT: ret57entry:58 %arrayidx = getelementptr inbounds i16, ptr %a, i64 159 %0 = load i16, ptr %arrayidx, align 260 %1 = tail call float @llvm.convert.from.fp16.f32(i16 %0)61 ret float %162}63 64define dso_local void @stored(ptr nocapture %a, double %b) local_unnamed_addr nounwind {65; CHECK-LABEL: stored:66; CHECK: ; %bb.0: ; %entry67; CHECK-NEXT: push r1668; CHECK-NEXT: push r1769; CHECK-NEXT: mov r30, r2270; CHECK-NEXT: mov r31, r2371; CHECK-NEXT: mov r22, r2072; CHECK-NEXT: mov r23, r2173; CHECK-NEXT: mov r20, r1874; CHECK-NEXT: mov r21, r1975; CHECK-NEXT: mov r18, r1676; CHECK-NEXT: mov r19, r1777; CHECK-NEXT: mov r16, r2478; CHECK-NEXT: mov r17, r2579; CHECK-NEXT: mov r24, r3080; CHECK-NEXT: mov r25, r3181; CHECK-NEXT: rcall __truncdfhf282; CHECK-NEXT: mov r30, r1683; CHECK-NEXT: mov r31, r1784; CHECK-NEXT: std Z+1, r2585; CHECK-NEXT: st Z, r2486; CHECK-NEXT: pop r1787; CHECK-NEXT: pop r1688; CHECK-NEXT: ret89entry:90 %0 = tail call i16 @llvm.convert.to.fp16.f64(double %b)91 store i16 %0, ptr %a, align 292 ret void93}94 95define dso_local void @storef(ptr nocapture %a, float %b) local_unnamed_addr nounwind {96; CHECK-LABEL: storef:97; CHECK: ; %bb.0: ; %entry98; CHECK-NEXT: push r1699; CHECK-NEXT: push r17100; CHECK-NEXT: mov r18, r22101; CHECK-NEXT: mov r19, r23102; CHECK-NEXT: mov r16, r24103; CHECK-NEXT: mov r17, r25104; CHECK-NEXT: mov r22, r20105; CHECK-NEXT: mov r23, r21106; CHECK-NEXT: mov r24, r18107; CHECK-NEXT: mov r25, r19108; CHECK-NEXT: rcall __truncsfhf2109; CHECK-NEXT: mov r30, r16110; CHECK-NEXT: mov r31, r17111; CHECK-NEXT: std Z+1, r25112; CHECK-NEXT: st Z, r24113; CHECK-NEXT: pop r17114; CHECK-NEXT: pop r16115; CHECK-NEXT: ret116entry:117 %0 = tail call i16 @llvm.convert.to.fp16.f32(float %b)118 store i16 %0, ptr %a, align 2119 ret void120}121 122define void @test_load_store(ptr %in, ptr %out) nounwind {123; CHECK-LABEL: test_load_store:124; CHECK: ; %bb.0:125; CHECK-NEXT: mov r30, r24126; CHECK-NEXT: mov r31, r25127; CHECK-NEXT: ld r24, Z128; CHECK-NEXT: ldd r25, Z+1129; CHECK-NEXT: mov r30, r22130; CHECK-NEXT: mov r31, r23131; CHECK-NEXT: std Z+1, r25132; CHECK-NEXT: st Z, r24133; CHECK-NEXT: ret134 %val = load half, ptr %in135 store half %val, ptr %out136 ret void137}138 139define i16 @test_bitcast_from_half(ptr %addr) nounwind {140; CHECK-LABEL: test_bitcast_from_half:141; CHECK: ; %bb.0:142; CHECK-NEXT: mov r30, r24143; CHECK-NEXT: mov r31, r25144; CHECK-NEXT: ld r24, Z145; CHECK-NEXT: ldd r25, Z+1146; CHECK-NEXT: ret147 %val = load half, ptr %addr148 %val_int = bitcast half %val to i16149 ret i16 %val_int150}151 152define void @test_bitcast_to_half(ptr %addr, i16 %in) nounwind {153; CHECK-LABEL: test_bitcast_to_half:154; CHECK: ; %bb.0:155; CHECK-NEXT: mov r30, r24156; CHECK-NEXT: mov r31, r25157; CHECK-NEXT: std Z+1, r23158; CHECK-NEXT: st Z, r22159; CHECK-NEXT: ret160 %val_fp = bitcast i16 %in to half161 store half %val_fp, ptr %addr162 ret void163}164 165define half @from_bits(i16 %x) nounwind {166; CHECK-LABEL: from_bits:167; CHECK: ; %bb.0:168; CHECK-NEXT: ret169 %res = bitcast i16 %x to half170 ret half %res171}172 173define i16 @to_bits(half %x) nounwind {174; CHECK-LABEL: to_bits:175; CHECK: ; %bb.0:176; CHECK-NEXT: ret177 %res = bitcast half %x to i16178 ret i16 %res179}180 181define float @test_extend32(ptr %addr) nounwind {182; CHECK-LABEL: test_extend32:183; CHECK: ; %bb.0:184; CHECK-NEXT: mov r30, r24185; CHECK-NEXT: mov r31, r25186; CHECK-NEXT: ld r24, Z187; CHECK-NEXT: ldd r25, Z+1188; CHECK-NEXT: rcall __extendhfsf2189; CHECK-NEXT: ret190 %val16 = load half, ptr %addr191 %val32 = fpext half %val16 to float192 ret float %val32193}194 195define double @test_extend64(ptr %addr) nounwind {196; CHECK-LABEL: test_extend64:197; CHECK: ; %bb.0:198; CHECK-NEXT: mov r30, r24199; CHECK-NEXT: mov r31, r25200; CHECK-NEXT: ld r24, Z201; CHECK-NEXT: ldd r25, Z+1202; CHECK-NEXT: rcall __extendhfsf2203; CHECK-NEXT: rcall __extendsfdf2204; CHECK-NEXT: ret205 %val16 = load half, ptr %addr206 %val32 = fpext half %val16 to double207 ret double %val32208}209 210define void @test_trunc32(float %in, ptr %addr) nounwind {211; CHECK-LABEL: test_trunc32:212; CHECK: ; %bb.0:213; CHECK-NEXT: push r16214; CHECK-NEXT: push r17215; CHECK-NEXT: mov r16, r20216; CHECK-NEXT: mov r17, r21217; CHECK-NEXT: rcall __truncsfhf2218; CHECK-NEXT: mov r30, r16219; CHECK-NEXT: mov r31, r17220; CHECK-NEXT: std Z+1, r25221; CHECK-NEXT: st Z, r24222; CHECK-NEXT: pop r17223; CHECK-NEXT: pop r16224; CHECK-NEXT: ret225 %val16 = fptrunc float %in to half226 store half %val16, ptr %addr227 ret void228}229 230define void @test_trunc64(double %in, ptr %addr) nounwind {231; CHECK-LABEL: test_trunc64:232; CHECK: ; %bb.0:233; CHECK-NEXT: rcall __truncdfhf2234; CHECK-NEXT: mov r30, r16235; CHECK-NEXT: mov r31, r17236; CHECK-NEXT: std Z+1, r25237; CHECK-NEXT: st Z, r24238; CHECK-NEXT: ret239 %val16 = fptrunc double %in to half240 store half %val16, ptr %addr241 ret void242}243 244define i64 @test_fptosi_i64(ptr %p) nounwind {245; CHECK-LABEL: test_fptosi_i64:246; CHECK: ; %bb.0:247; CHECK-NEXT: mov r30, r24248; CHECK-NEXT: mov r31, r25249; CHECK-NEXT: ld r24, Z250; CHECK-NEXT: ldd r25, Z+1251; CHECK-NEXT: rcall __extendhfsf2252; CHECK-NEXT: rcall __fixsfdi253; CHECK-NEXT: ret254 %a = load half, ptr %p, align 2255 %r = fptosi half %a to i64256 ret i64 %r257}258 259define void @test_sitofp_i64(i64 %a, ptr %p) nounwind {260; CHECK-LABEL: test_sitofp_i64:261; CHECK: ; %bb.0:262; CHECK-NEXT: rcall __floatdisf263; CHECK-NEXT: rcall __truncsfhf2264; CHECK-NEXT: mov r30, r16265; CHECK-NEXT: mov r31, r17266; CHECK-NEXT: std Z+1, r25267; CHECK-NEXT: st Z, r24268; CHECK-NEXT: ret269 %r = sitofp i64 %a to half270 store half %r, ptr %p271 ret void272}273 274define i64 @test_fptoui_i64(ptr %p) nounwind {275; CHECK-LABEL: test_fptoui_i64:276; CHECK: ; %bb.0:277; CHECK-NEXT: mov r30, r24278; CHECK-NEXT: mov r31, r25279; CHECK-NEXT: ld r24, Z280; CHECK-NEXT: ldd r25, Z+1281; CHECK-NEXT: rcall __extendhfsf2282; CHECK-NEXT: rcall __fixunssfdi283; CHECK-NEXT: ret284 %a = load half, ptr %p, align 2285 %r = fptoui half %a to i64286 ret i64 %r287}288 289define void @test_uitofp_i64(i64 %a, ptr %p) nounwind {290; CHECK-LABEL: test_uitofp_i64:291; CHECK: ; %bb.0:292; CHECK-NEXT: rcall __floatundisf293; CHECK-NEXT: rcall __truncsfhf2294; CHECK-NEXT: mov r30, r16295; CHECK-NEXT: mov r31, r17296; CHECK-NEXT: std Z+1, r25297; CHECK-NEXT: st Z, r24298; CHECK-NEXT: ret299 %r = uitofp i64 %a to half300 store half %r, ptr %p301 ret void302}303 304define <2 x float> @test_extend32_vec2(ptr %p) nounwind {305; CHECK-LABEL: test_extend32_vec2:306; CHECK: ; %bb.0:307; CHECK-NEXT: push r12308; CHECK-NEXT: push r13309; CHECK-NEXT: push r14310; CHECK-NEXT: push r15311; CHECK-NEXT: push r16312; CHECK-NEXT: push r17313; CHECK-NEXT: mov r30, r24314; CHECK-NEXT: mov r31, r25315; CHECK-NEXT: ld r24, Z316; CHECK-NEXT: ldd r25, Z+1317; CHECK-NEXT: mov r12, r30318; CHECK-NEXT: mov r13, r31319; CHECK-NEXT: rcall __extendhfsf2320; CHECK-NEXT: mov r16, r22321; CHECK-NEXT: mov r17, r23322; CHECK-NEXT: mov r14, r24323; CHECK-NEXT: mov r15, r25324; CHECK-NEXT: mov r30, r12325; CHECK-NEXT: mov r31, r13326; CHECK-NEXT: ldd r24, Z+2327; CHECK-NEXT: ldd r25, Z+3328; CHECK-NEXT: rcall __extendhfsf2329; CHECK-NEXT: mov r18, r16330; CHECK-NEXT: mov r19, r17331; CHECK-NEXT: mov r20, r14332; CHECK-NEXT: mov r21, r15333; CHECK-NEXT: pop r17334; CHECK-NEXT: pop r16335; CHECK-NEXT: pop r15336; CHECK-NEXT: pop r14337; CHECK-NEXT: pop r13338; CHECK-NEXT: pop r12339; CHECK-NEXT: ret340 %a = load <2 x half>, ptr %p, align 8341 %b = fpext <2 x half> %a to <2 x float>342 ret <2 x float> %b343}344 345define <1 x double> @test_extend64_vec1(ptr %p) nounwind {346; CHECK-LABEL: test_extend64_vec1:347; CHECK: ; %bb.0:348; CHECK-NEXT: mov r30, r24349; CHECK-NEXT: mov r31, r25350; CHECK-NEXT: ld r24, Z351; CHECK-NEXT: ldd r25, Z+1352; CHECK-NEXT: rcall __extendhfsf2353; CHECK-NEXT: rcall __extendsfdf2354; CHECK-NEXT: ret355 %a = load <1 x half>, ptr %p, align 8356 %b = fpext <1 x half> %a to <1 x double>357 ret <1 x double> %b358}359 360define void @test_trunc32_vec2(<2 x float> %a, ptr %p) nounwind {361; CHECK-LABEL: test_trunc32_vec2:362; CHECK: ; %bb.0:363; CHECK-NEXT: push r12364; CHECK-NEXT: push r13365; CHECK-NEXT: push r14366; CHECK-NEXT: push r15367; CHECK-NEXT: mov r14, r20368; CHECK-NEXT: mov r15, r21369; CHECK-NEXT: mov r12, r18370; CHECK-NEXT: mov r13, r19371; CHECK-NEXT: rcall __truncsfhf2372; CHECK-NEXT: mov r30, r16373; CHECK-NEXT: mov r31, r17374; CHECK-NEXT: std Z+3, r25375; CHECK-NEXT: std Z+2, r24376; CHECK-NEXT: mov r22, r12377; CHECK-NEXT: mov r23, r13378; CHECK-NEXT: mov r24, r14379; CHECK-NEXT: mov r25, r15380; CHECK-NEXT: rcall __truncsfhf2381; CHECK-NEXT: mov r30, r16382; CHECK-NEXT: mov r31, r17383; CHECK-NEXT: std Z+1, r25384; CHECK-NEXT: st Z, r24385; CHECK-NEXT: pop r15386; CHECK-NEXT: pop r14387; CHECK-NEXT: pop r13388; CHECK-NEXT: pop r12389; CHECK-NEXT: ret390 %v = fptrunc <2 x float> %a to <2 x half>391 store <2 x half> %v, ptr %p392 ret void393}394 395define void @test_trunc64_vec1(<1 x double> %a, ptr %p) nounwind {396; CHECK-LABEL: test_trunc64_vec1:397; CHECK: ; %bb.0:398; CHECK-NEXT: rcall __truncdfhf2399; CHECK-NEXT: mov r30, r16400; CHECK-NEXT: mov r31, r17401; CHECK-NEXT: std Z+1, r25402; CHECK-NEXT: st Z, r24403; CHECK-NEXT: ret404 %v = fptrunc <1 x double> %a to <1 x half>405 store <1 x half> %v, ptr %p406 ret void407}408 409define float @test_sitofp_fadd_i32(i32 %a, ptr %b) nounwind {410; CHECK-LABEL: test_sitofp_fadd_i32:411; CHECK: ; %bb.0:412; CHECK-NEXT: push r12413; CHECK-NEXT: push r13414; CHECK-NEXT: push r14415; CHECK-NEXT: push r15416; CHECK-NEXT: push r16417; CHECK-NEXT: push r17418; CHECK-NEXT: mov r16, r20419; CHECK-NEXT: mov r17, r21420; CHECK-NEXT: rcall __floatsisf421; CHECK-NEXT: rcall __truncsfhf2422; CHECK-NEXT: mov r14, r24423; CHECK-NEXT: mov r15, r25424; CHECK-NEXT: mov r30, r16425; CHECK-NEXT: mov r31, r17426; CHECK-NEXT: ld r24, Z427; CHECK-NEXT: ldd r25, Z+1428; CHECK-NEXT: rcall __extendhfsf2429; CHECK-NEXT: mov r16, r22430; CHECK-NEXT: mov r17, r23431; CHECK-NEXT: mov r12, r24432; CHECK-NEXT: mov r13, r25433; CHECK-NEXT: mov r24, r14434; CHECK-NEXT: mov r25, r15435; CHECK-NEXT: rcall __extendhfsf2436; CHECK-NEXT: mov r18, r22437; CHECK-NEXT: mov r19, r23438; CHECK-NEXT: mov r20, r24439; CHECK-NEXT: mov r21, r25440; CHECK-NEXT: mov r22, r16441; CHECK-NEXT: mov r23, r17442; CHECK-NEXT: mov r24, r12443; CHECK-NEXT: mov r25, r13444; CHECK-NEXT: rcall __addsf3445; CHECK-NEXT: rcall __truncsfhf2446; CHECK-NEXT: rcall __extendhfsf2447; CHECK-NEXT: pop r17448; CHECK-NEXT: pop r16449; CHECK-NEXT: pop r15450; CHECK-NEXT: pop r14451; CHECK-NEXT: pop r13452; CHECK-NEXT: pop r12453; CHECK-NEXT: ret454 %tmp0 = load half, ptr %b455 %tmp1 = sitofp i32 %a to half456 %tmp2 = fadd half %tmp0, %tmp1457 %tmp3 = fpext half %tmp2 to float458 ret float %tmp3459}460 461define half @chained_fp_ops(half %x) {462; CHECK-LABEL: chained_fp_ops:463; CHECK: ; %bb.0: ; %start464; CHECK-NEXT: rcall __extendhfsf2465; CHECK-NEXT: mov r18, r22466; CHECK-NEXT: mov r19, r23467; CHECK-NEXT: mov r20, r24468; CHECK-NEXT: mov r21, r25469; CHECK-NEXT: rcall __addsf3470; CHECK-NEXT: rcall __truncsfhf2471; CHECK-NEXT: rcall __extendhfsf2472; CHECK-NEXT: ldi r18, 0473; CHECK-NEXT: ldi r19, 0474; CHECK-NEXT: ldi r20, 0475; CHECK-NEXT: ldi r21, 63476; CHECK-NEXT: rcall __mulsf3477; CHECK-NEXT: rcall __truncsfhf2478; CHECK-NEXT: ret479start:480 %y = fmul half %x, 0xH4000481 %z = fdiv half %y, 0xH4000482 ret half %z483}484 485define half @test_select_cc(half) nounwind {486; CHECK-LABEL: test_select_cc:487; CHECK: ; %bb.0:488; CHECK-NEXT: push r16489; CHECK-NEXT: push r17490; CHECK-NEXT: rcall __extendhfsf2491; CHECK-NEXT: ldi r16, 0492; CHECK-NEXT: ldi r17, 0493; CHECK-NEXT: mov r18, r16494; CHECK-NEXT: mov r19, r17495; CHECK-NEXT: mov r20, r16496; CHECK-NEXT: mov r21, r17497; CHECK-NEXT: rcall __nesf2498; CHECK-NEXT: cpi r24, 0499; CHECK-NEXT: breq .LBB25_2500; CHECK-NEXT: ; %bb.1:501; CHECK-NEXT: ldi r16, 0502; CHECK-NEXT: ldi r17, 60503; CHECK-NEXT: .LBB25_2:504; CHECK-NEXT: mov r24, r16505; CHECK-NEXT: mov r25, r17506; CHECK-NEXT: pop r17507; CHECK-NEXT: pop r16508; CHECK-NEXT: ret509 %2 = fcmp une half %0, 0xH0000510 %3 = uitofp i1 %2 to half511 ret half %3512}513 514define half @fabs(half %x) nounwind {515; CHECK-LABEL: fabs:516; CHECK: ; %bb.0:517; CHECK-NEXT: andi r25, 127518; CHECK-NEXT: ret519 %a = call half @llvm.fabs.f16(half %x)520 ret half %a521}522 523define half @fcopysign(half %x, half %y) nounwind {524; CHECK-LABEL: fcopysign:525; CHECK: ; %bb.0:526; CHECK-NEXT: andi r22, 0527; CHECK-NEXT: andi r23, 128528; CHECK-NEXT: andi r25, 127529; CHECK-NEXT: or r24, r22530; CHECK-NEXT: or r25, r23531; CHECK-NEXT: ret532 %a = call half @llvm.copysign.f16(half %x, half %y)533 ret half %a534}535