| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py |
| ; RUN: llc %s -o - -mtriple=avr | FileCheck %s |
| |
| ; Tests for various operations on half precison float. Much of the test is |
| ; copied from test/CodeGen/X86/half.ll. |
| |
| define void @store(half %x, ptr %p) nounwind { |
| ; CHECK-LABEL: store: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: mov r30, r22 |
| ; CHECK-NEXT: mov r31, r23 |
| ; CHECK-NEXT: std Z+1, r25 |
| ; CHECK-NEXT: st Z, r24 |
| ; CHECK-NEXT: ret |
| store half %x, ptr %p |
| ret void |
| } |
| |
| define half @return(ptr %p) nounwind { |
| ; CHECK-LABEL: return: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: mov r30, r24 |
| ; CHECK-NEXT: mov r31, r25 |
| ; CHECK-NEXT: ld r24, Z |
| ; CHECK-NEXT: ldd r25, Z+1 |
| ; CHECK-NEXT: ret |
| %r = load half, ptr %p |
| ret half %r |
| } |
| |
| define dso_local double @loadd(ptr nocapture readonly %a) local_unnamed_addr nounwind { |
| ; CHECK-LABEL: loadd: |
| ; CHECK: ; %bb.0: ; %entry |
| ; CHECK-NEXT: mov r30, r24 |
| ; CHECK-NEXT: mov r31, r25 |
| ; CHECK-NEXT: ldd r24, Z+2 |
| ; CHECK-NEXT: ldd r25, Z+3 |
| ; CHECK-NEXT: rcall __extendhfsf2 |
| ; CHECK-NEXT: rcall __extendsfdf2 |
| ; CHECK-NEXT: ret |
| entry: |
| %arrayidx = getelementptr inbounds i16, ptr %a, i64 1 |
| %0 = load i16, ptr %arrayidx, align 2 |
| %1 = tail call double @llvm.convert.from.fp16.f64(i16 %0) |
| ret double %1 |
| } |
| |
| define dso_local float @loadf(ptr nocapture readonly %a) local_unnamed_addr nounwind { |
| ; CHECK-LABEL: loadf: |
| ; CHECK: ; %bb.0: ; %entry |
| ; CHECK-NEXT: mov r30, r24 |
| ; CHECK-NEXT: mov r31, r25 |
| ; CHECK-NEXT: ldd r24, Z+2 |
| ; CHECK-NEXT: ldd r25, Z+3 |
| ; CHECK-NEXT: rcall __extendhfsf2 |
| ; CHECK-NEXT: ret |
| entry: |
| %arrayidx = getelementptr inbounds i16, ptr %a, i64 1 |
| %0 = load i16, ptr %arrayidx, align 2 |
| %1 = tail call float @llvm.convert.from.fp16.f32(i16 %0) |
| ret float %1 |
| } |
| |
| define dso_local void @stored(ptr nocapture %a, double %b) local_unnamed_addr nounwind { |
| ; CHECK-LABEL: stored: |
| ; CHECK: ; %bb.0: ; %entry |
| ; CHECK-NEXT: push r16 |
| ; CHECK-NEXT: push r17 |
| ; CHECK-NEXT: mov r30, r22 |
| ; CHECK-NEXT: mov r31, r23 |
| ; CHECK-NEXT: mov r22, r20 |
| ; CHECK-NEXT: mov r23, r21 |
| ; CHECK-NEXT: mov r20, r18 |
| ; CHECK-NEXT: mov r21, r19 |
| ; CHECK-NEXT: mov r18, r16 |
| ; CHECK-NEXT: mov r19, r17 |
| ; CHECK-NEXT: mov r16, r24 |
| ; CHECK-NEXT: mov r17, r25 |
| ; CHECK-NEXT: mov r24, r30 |
| ; CHECK-NEXT: mov r25, r31 |
| ; CHECK-NEXT: rcall __truncdfhf2 |
| ; CHECK-NEXT: mov r30, r16 |
| ; CHECK-NEXT: mov r31, r17 |
| ; CHECK-NEXT: std Z+1, r25 |
| ; CHECK-NEXT: st Z, r24 |
| ; CHECK-NEXT: pop r17 |
| ; CHECK-NEXT: pop r16 |
| ; CHECK-NEXT: ret |
| entry: |
| %0 = tail call i16 @llvm.convert.to.fp16.f64(double %b) |
| store i16 %0, ptr %a, align 2 |
| ret void |
| } |
| |
| define dso_local void @storef(ptr nocapture %a, float %b) local_unnamed_addr nounwind { |
| ; CHECK-LABEL: storef: |
| ; CHECK: ; %bb.0: ; %entry |
| ; CHECK-NEXT: push r16 |
| ; CHECK-NEXT: push r17 |
| ; CHECK-NEXT: mov r18, r22 |
| ; CHECK-NEXT: mov r19, r23 |
| ; CHECK-NEXT: mov r16, r24 |
| ; CHECK-NEXT: mov r17, r25 |
| ; CHECK-NEXT: mov r22, r20 |
| ; CHECK-NEXT: mov r23, r21 |
| ; CHECK-NEXT: mov r24, r18 |
| ; CHECK-NEXT: mov r25, r19 |
| ; CHECK-NEXT: rcall __truncsfhf2 |
| ; CHECK-NEXT: mov r30, r16 |
| ; CHECK-NEXT: mov r31, r17 |
| ; CHECK-NEXT: std Z+1, r25 |
| ; CHECK-NEXT: st Z, r24 |
| ; CHECK-NEXT: pop r17 |
| ; CHECK-NEXT: pop r16 |
| ; CHECK-NEXT: ret |
| entry: |
| %0 = tail call i16 @llvm.convert.to.fp16.f32(float %b) |
| store i16 %0, ptr %a, align 2 |
| ret void |
| } |
| |
| define void @test_load_store(ptr %in, ptr %out) nounwind { |
| ; CHECK-LABEL: test_load_store: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: mov r30, r24 |
| ; CHECK-NEXT: mov r31, r25 |
| ; CHECK-NEXT: ld r24, Z |
| ; CHECK-NEXT: ldd r25, Z+1 |
| ; CHECK-NEXT: mov r30, r22 |
| ; CHECK-NEXT: mov r31, r23 |
| ; CHECK-NEXT: std Z+1, r25 |
| ; CHECK-NEXT: st Z, r24 |
| ; CHECK-NEXT: ret |
| %val = load half, ptr %in |
| store half %val, ptr %out |
| ret void |
| } |
| |
| define i16 @test_bitcast_from_half(ptr %addr) nounwind { |
| ; CHECK-LABEL: test_bitcast_from_half: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: mov r30, r24 |
| ; CHECK-NEXT: mov r31, r25 |
| ; CHECK-NEXT: ld r24, Z |
| ; CHECK-NEXT: ldd r25, Z+1 |
| ; CHECK-NEXT: ret |
| %val = load half, ptr %addr |
| %val_int = bitcast half %val to i16 |
| ret i16 %val_int |
| } |
| |
| define void @test_bitcast_to_half(ptr %addr, i16 %in) nounwind { |
| ; CHECK-LABEL: test_bitcast_to_half: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: mov r30, r24 |
| ; CHECK-NEXT: mov r31, r25 |
| ; CHECK-NEXT: std Z+1, r23 |
| ; CHECK-NEXT: st Z, r22 |
| ; CHECK-NEXT: ret |
| %val_fp = bitcast i16 %in to half |
| store half %val_fp, ptr %addr |
| ret void |
| } |
| |
| define half @from_bits(i16 %x) nounwind { |
| ; CHECK-LABEL: from_bits: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: ret |
| %res = bitcast i16 %x to half |
| ret half %res |
| } |
| |
| define i16 @to_bits(half %x) nounwind { |
| ; CHECK-LABEL: to_bits: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: ret |
| %res = bitcast half %x to i16 |
| ret i16 %res |
| } |
| |
| define float @test_extend32(ptr %addr) nounwind { |
| ; CHECK-LABEL: test_extend32: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: mov r30, r24 |
| ; CHECK-NEXT: mov r31, r25 |
| ; CHECK-NEXT: ld r24, Z |
| ; CHECK-NEXT: ldd r25, Z+1 |
| ; CHECK-NEXT: rcall __extendhfsf2 |
| ; CHECK-NEXT: ret |
| %val16 = load half, ptr %addr |
| %val32 = fpext half %val16 to float |
| ret float %val32 |
| } |
| |
| define double @test_extend64(ptr %addr) nounwind { |
| ; CHECK-LABEL: test_extend64: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: mov r30, r24 |
| ; CHECK-NEXT: mov r31, r25 |
| ; CHECK-NEXT: ld r24, Z |
| ; CHECK-NEXT: ldd r25, Z+1 |
| ; CHECK-NEXT: rcall __extendhfsf2 |
| ; CHECK-NEXT: rcall __extendsfdf2 |
| ; CHECK-NEXT: ret |
| %val16 = load half, ptr %addr |
| %val32 = fpext half %val16 to double |
| ret double %val32 |
| } |
| |
| define void @test_trunc32(float %in, ptr %addr) nounwind { |
| ; CHECK-LABEL: test_trunc32: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: push r16 |
| ; CHECK-NEXT: push r17 |
| ; CHECK-NEXT: mov r16, r20 |
| ; CHECK-NEXT: mov r17, r21 |
| ; CHECK-NEXT: rcall __truncsfhf2 |
| ; CHECK-NEXT: mov r30, r16 |
| ; CHECK-NEXT: mov r31, r17 |
| ; CHECK-NEXT: std Z+1, r25 |
| ; CHECK-NEXT: st Z, r24 |
| ; CHECK-NEXT: pop r17 |
| ; CHECK-NEXT: pop r16 |
| ; CHECK-NEXT: ret |
| %val16 = fptrunc float %in to half |
| store half %val16, ptr %addr |
| ret void |
| } |
| |
| define void @test_trunc64(double %in, ptr %addr) nounwind { |
| ; CHECK-LABEL: test_trunc64: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: rcall __truncdfhf2 |
| ; CHECK-NEXT: mov r30, r16 |
| ; CHECK-NEXT: mov r31, r17 |
| ; CHECK-NEXT: std Z+1, r25 |
| ; CHECK-NEXT: st Z, r24 |
| ; CHECK-NEXT: ret |
| %val16 = fptrunc double %in to half |
| store half %val16, ptr %addr |
| ret void |
| } |
| |
| define i64 @test_fptosi_i64(ptr %p) nounwind { |
| ; CHECK-LABEL: test_fptosi_i64: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: mov r30, r24 |
| ; CHECK-NEXT: mov r31, r25 |
| ; CHECK-NEXT: ld r24, Z |
| ; CHECK-NEXT: ldd r25, Z+1 |
| ; CHECK-NEXT: rcall __extendhfsf2 |
| ; CHECK-NEXT: rcall __fixsfdi |
| ; CHECK-NEXT: ret |
| %a = load half, ptr %p, align 2 |
| %r = fptosi half %a to i64 |
| ret i64 %r |
| } |
| |
| define void @test_sitofp_i64(i64 %a, ptr %p) nounwind { |
| ; CHECK-LABEL: test_sitofp_i64: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: rcall __floatdisf |
| ; CHECK-NEXT: rcall __truncsfhf2 |
| ; CHECK-NEXT: mov r30, r16 |
| ; CHECK-NEXT: mov r31, r17 |
| ; CHECK-NEXT: std Z+1, r25 |
| ; CHECK-NEXT: st Z, r24 |
| ; CHECK-NEXT: ret |
| %r = sitofp i64 %a to half |
| store half %r, ptr %p |
| ret void |
| } |
| |
| define i64 @test_fptoui_i64(ptr %p) nounwind { |
| ; CHECK-LABEL: test_fptoui_i64: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: mov r30, r24 |
| ; CHECK-NEXT: mov r31, r25 |
| ; CHECK-NEXT: ld r24, Z |
| ; CHECK-NEXT: ldd r25, Z+1 |
| ; CHECK-NEXT: rcall __extendhfsf2 |
| ; CHECK-NEXT: rcall __fixunssfdi |
| ; CHECK-NEXT: ret |
| %a = load half, ptr %p, align 2 |
| %r = fptoui half %a to i64 |
| ret i64 %r |
| } |
| |
| define void @test_uitofp_i64(i64 %a, ptr %p) nounwind { |
| ; CHECK-LABEL: test_uitofp_i64: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: rcall __floatundisf |
| ; CHECK-NEXT: rcall __truncsfhf2 |
| ; CHECK-NEXT: mov r30, r16 |
| ; CHECK-NEXT: mov r31, r17 |
| ; CHECK-NEXT: std Z+1, r25 |
| ; CHECK-NEXT: st Z, r24 |
| ; CHECK-NEXT: ret |
| %r = uitofp i64 %a to half |
| store half %r, ptr %p |
| ret void |
| } |
| |
| define <2 x float> @test_extend32_vec2(ptr %p) nounwind { |
| ; CHECK-LABEL: test_extend32_vec2: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: push r12 |
| ; CHECK-NEXT: push r13 |
| ; CHECK-NEXT: push r14 |
| ; CHECK-NEXT: push r15 |
| ; CHECK-NEXT: push r16 |
| ; CHECK-NEXT: push r17 |
| ; CHECK-NEXT: mov r30, r24 |
| ; CHECK-NEXT: mov r31, r25 |
| ; CHECK-NEXT: ld r24, Z |
| ; CHECK-NEXT: ldd r25, Z+1 |
| ; CHECK-NEXT: mov r12, r30 |
| ; CHECK-NEXT: mov r13, r31 |
| ; CHECK-NEXT: rcall __extendhfsf2 |
| ; CHECK-NEXT: mov r16, r22 |
| ; CHECK-NEXT: mov r17, r23 |
| ; CHECK-NEXT: mov r14, r24 |
| ; CHECK-NEXT: mov r15, r25 |
| ; CHECK-NEXT: mov r30, r12 |
| ; CHECK-NEXT: mov r31, r13 |
| ; CHECK-NEXT: ldd r24, Z+2 |
| ; CHECK-NEXT: ldd r25, Z+3 |
| ; CHECK-NEXT: rcall __extendhfsf2 |
| ; CHECK-NEXT: mov r18, r16 |
| ; CHECK-NEXT: mov r19, r17 |
| ; CHECK-NEXT: mov r20, r14 |
| ; CHECK-NEXT: mov r21, r15 |
| ; CHECK-NEXT: pop r17 |
| ; CHECK-NEXT: pop r16 |
| ; CHECK-NEXT: pop r15 |
| ; CHECK-NEXT: pop r14 |
| ; CHECK-NEXT: pop r13 |
| ; CHECK-NEXT: pop r12 |
| ; CHECK-NEXT: ret |
| %a = load <2 x half>, ptr %p, align 8 |
| %b = fpext <2 x half> %a to <2 x float> |
| ret <2 x float> %b |
| } |
| |
| define <1 x double> @test_extend64_vec1(ptr %p) nounwind { |
| ; CHECK-LABEL: test_extend64_vec1: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: mov r30, r24 |
| ; CHECK-NEXT: mov r31, r25 |
| ; CHECK-NEXT: ld r24, Z |
| ; CHECK-NEXT: ldd r25, Z+1 |
| ; CHECK-NEXT: rcall __extendhfsf2 |
| ; CHECK-NEXT: rcall __extendsfdf2 |
| ; CHECK-NEXT: ret |
| %a = load <1 x half>, ptr %p, align 8 |
| %b = fpext <1 x half> %a to <1 x double> |
| ret <1 x double> %b |
| } |
| |
| define void @test_trunc32_vec2(<2 x float> %a, ptr %p) nounwind { |
| ; CHECK-LABEL: test_trunc32_vec2: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: push r12 |
| ; CHECK-NEXT: push r13 |
| ; CHECK-NEXT: push r14 |
| ; CHECK-NEXT: push r15 |
| ; CHECK-NEXT: mov r14, r20 |
| ; CHECK-NEXT: mov r15, r21 |
| ; CHECK-NEXT: mov r12, r18 |
| ; CHECK-NEXT: mov r13, r19 |
| ; CHECK-NEXT: rcall __truncsfhf2 |
| ; CHECK-NEXT: mov r30, r16 |
| ; CHECK-NEXT: mov r31, r17 |
| ; CHECK-NEXT: std Z+3, r25 |
| ; CHECK-NEXT: std Z+2, r24 |
| ; CHECK-NEXT: mov r22, r12 |
| ; CHECK-NEXT: mov r23, r13 |
| ; CHECK-NEXT: mov r24, r14 |
| ; CHECK-NEXT: mov r25, r15 |
| ; CHECK-NEXT: rcall __truncsfhf2 |
| ; CHECK-NEXT: mov r30, r16 |
| ; CHECK-NEXT: mov r31, r17 |
| ; CHECK-NEXT: std Z+1, r25 |
| ; CHECK-NEXT: st Z, r24 |
| ; CHECK-NEXT: pop r15 |
| ; CHECK-NEXT: pop r14 |
| ; CHECK-NEXT: pop r13 |
| ; CHECK-NEXT: pop r12 |
| ; CHECK-NEXT: ret |
| %v = fptrunc <2 x float> %a to <2 x half> |
| store <2 x half> %v, ptr %p |
| ret void |
| } |
| |
| define void @test_trunc64_vec1(<1 x double> %a, ptr %p) nounwind { |
| ; CHECK-LABEL: test_trunc64_vec1: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: rcall __truncdfhf2 |
| ; CHECK-NEXT: mov r30, r16 |
| ; CHECK-NEXT: mov r31, r17 |
| ; CHECK-NEXT: std Z+1, r25 |
| ; CHECK-NEXT: st Z, r24 |
| ; CHECK-NEXT: ret |
| %v = fptrunc <1 x double> %a to <1 x half> |
| store <1 x half> %v, ptr %p |
| ret void |
| } |
| |
| define float @test_sitofp_fadd_i32(i32 %a, ptr %b) nounwind { |
| ; CHECK-LABEL: test_sitofp_fadd_i32: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: push r12 |
| ; CHECK-NEXT: push r13 |
| ; CHECK-NEXT: push r14 |
| ; CHECK-NEXT: push r15 |
| ; CHECK-NEXT: push r16 |
| ; CHECK-NEXT: push r17 |
| ; CHECK-NEXT: mov r16, r20 |
| ; CHECK-NEXT: mov r17, r21 |
| ; CHECK-NEXT: rcall __floatsisf |
| ; CHECK-NEXT: rcall __truncsfhf2 |
| ; CHECK-NEXT: mov r14, r24 |
| ; CHECK-NEXT: mov r15, r25 |
| ; CHECK-NEXT: mov r30, r16 |
| ; CHECK-NEXT: mov r31, r17 |
| ; CHECK-NEXT: ld r24, Z |
| ; CHECK-NEXT: ldd r25, Z+1 |
| ; CHECK-NEXT: rcall __extendhfsf2 |
| ; CHECK-NEXT: mov r16, r22 |
| ; CHECK-NEXT: mov r17, r23 |
| ; CHECK-NEXT: mov r12, r24 |
| ; CHECK-NEXT: mov r13, r25 |
| ; CHECK-NEXT: mov r24, r14 |
| ; CHECK-NEXT: mov r25, r15 |
| ; CHECK-NEXT: rcall __extendhfsf2 |
| ; CHECK-NEXT: mov r18, r22 |
| ; CHECK-NEXT: mov r19, r23 |
| ; CHECK-NEXT: mov r20, r24 |
| ; CHECK-NEXT: mov r21, r25 |
| ; CHECK-NEXT: mov r22, r16 |
| ; CHECK-NEXT: mov r23, r17 |
| ; CHECK-NEXT: mov r24, r12 |
| ; CHECK-NEXT: mov r25, r13 |
| ; CHECK-NEXT: rcall __addsf3 |
| ; CHECK-NEXT: rcall __truncsfhf2 |
| ; CHECK-NEXT: rcall __extendhfsf2 |
| ; CHECK-NEXT: pop r17 |
| ; CHECK-NEXT: pop r16 |
| ; CHECK-NEXT: pop r15 |
| ; CHECK-NEXT: pop r14 |
| ; CHECK-NEXT: pop r13 |
| ; CHECK-NEXT: pop r12 |
| ; CHECK-NEXT: ret |
| %tmp0 = load half, ptr %b |
| %tmp1 = sitofp i32 %a to half |
| %tmp2 = fadd half %tmp0, %tmp1 |
| %tmp3 = fpext half %tmp2 to float |
| ret float %tmp3 |
| } |
| |
| define half @chained_fp_ops(half %x) { |
| ; CHECK-LABEL: chained_fp_ops: |
| ; CHECK: ; %bb.0: ; %start |
| ; CHECK-NEXT: rcall __extendhfsf2 |
| ; CHECK-NEXT: mov r18, r22 |
| ; CHECK-NEXT: mov r19, r23 |
| ; CHECK-NEXT: mov r20, r24 |
| ; CHECK-NEXT: mov r21, r25 |
| ; CHECK-NEXT: rcall __addsf3 |
| ; CHECK-NEXT: rcall __truncsfhf2 |
| ; CHECK-NEXT: rcall __extendhfsf2 |
| ; CHECK-NEXT: ldi r18, 0 |
| ; CHECK-NEXT: ldi r19, 0 |
| ; CHECK-NEXT: ldi r20, 0 |
| ; CHECK-NEXT: ldi r21, 63 |
| ; CHECK-NEXT: rcall __mulsf3 |
| ; CHECK-NEXT: rcall __truncsfhf2 |
| ; CHECK-NEXT: ret |
| start: |
| %y = fmul half %x, 0xH4000 |
| %z = fdiv half %y, 0xH4000 |
| ret half %z |
| } |
| |
| define half @test_select_cc(half) nounwind { |
| ; CHECK-LABEL: test_select_cc: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: push r16 |
| ; CHECK-NEXT: push r17 |
| ; CHECK-NEXT: rcall __extendhfsf2 |
| ; CHECK-NEXT: ldi r16, 0 |
| ; CHECK-NEXT: ldi r17, 0 |
| ; CHECK-NEXT: mov r18, r16 |
| ; CHECK-NEXT: mov r19, r17 |
| ; CHECK-NEXT: mov r20, r16 |
| ; CHECK-NEXT: mov r21, r17 |
| ; CHECK-NEXT: rcall __nesf2 |
| ; CHECK-NEXT: cpi r24, 0 |
| ; CHECK-NEXT: breq .LBB25_2 |
| ; CHECK-NEXT: ; %bb.1: |
| ; CHECK-NEXT: ldi r16, 0 |
| ; CHECK-NEXT: ldi r17, 60 |
| ; CHECK-NEXT: .LBB25_2: |
| ; CHECK-NEXT: mov r24, r16 |
| ; CHECK-NEXT: mov r25, r17 |
| ; CHECK-NEXT: pop r17 |
| ; CHECK-NEXT: pop r16 |
| ; CHECK-NEXT: ret |
| %2 = fcmp une half %0, 0xH0000 |
| %3 = uitofp i1 %2 to half |
| ret half %3 |
| } |
| |
| define half @fabs(half %x) nounwind { |
| ; CHECK-LABEL: fabs: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: andi r25, 127 |
| ; CHECK-NEXT: ret |
| %a = call half @llvm.fabs.f16(half %x) |
| ret half %a |
| } |
| |
| define half @fcopysign(half %x, half %y) nounwind { |
| ; CHECK-LABEL: fcopysign: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: andi r22, 0 |
| ; CHECK-NEXT: andi r23, 128 |
| ; CHECK-NEXT: andi r25, 127 |
| ; CHECK-NEXT: or r24, r22 |
| ; CHECK-NEXT: or r25, r23 |
| ; CHECK-NEXT: ret |
| %a = call half @llvm.copysign.f16(half %x, half %y) |
| ret half %a |
| } |