| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py | |
| ; RUN: llc %s -o - -mtriple=sparc-linux-gnu | FileCheck %s -check-prefixes=CHECK,SPARC32,V8 | |
| ; RUN: llc %s -o - -mtriple=sparcel-linux-gnu | FileCheck %s -check-prefixes=CHECK,SPARC32,V8 | |
| ; RUN: llc %s -o - -mtriple=sparc-linux-gnu -mattr=v9 | FileCheck %s -check-prefixes=CHECK,SPARC32,V9 | |
| ; RUN: llc %s -o - -mtriple=sparc64-unknown-linux | FileCheck %s -check-prefixes=CHECK,SPARC64 | |
| ; 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: retl | |
| ; CHECK-NEXT: sth %o0, [%o1] | |
| store half %x, ptr %p | |
| ret void | |
| } | |
| define half @return(ptr %p) nounwind { | |
| ; CHECK-LABEL: return: | |
| ; CHECK: ! %bb.0: | |
| ; CHECK-NEXT: retl | |
| ; CHECK-NEXT: lduh [%o0], %o0 | |
| %r = load half, ptr %p | |
| ret half %r | |
| } | |
| define void @test_load_store(ptr %in, ptr %out) nounwind { | |
| ; CHECK-LABEL: test_load_store: | |
| ; CHECK: ! %bb.0: | |
| ; CHECK-NEXT: lduh [%o0], %o0 | |
| ; CHECK-NEXT: retl | |
| ; CHECK-NEXT: sth %o0, [%o1] | |
| %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: retl | |
| ; CHECK-NEXT: lduh [%o0], %o0 | |
| %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: retl | |
| ; CHECK-NEXT: sth %o1, [%o0] | |
| %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: retl | |
| ; CHECK-NEXT: nop | |
| %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: retl | |
| ; CHECK-NEXT: nop | |
| %res = bitcast half %x to i16 | |
| ret i16 %res | |
| } | |
| define float @test_extend32(ptr %addr) nounwind { | |
| ; SPARC32-LABEL: test_extend32: | |
| ; SPARC32: ! %bb.0: | |
| ; SPARC32-NEXT: save %sp, -96, %sp | |
| ; SPARC32-NEXT: call __extendhfsf2 | |
| ; SPARC32-NEXT: lduh [%i0], %o0 | |
| ; SPARC32-NEXT: ret | |
| ; SPARC32-NEXT: restore | |
| ; | |
| ; SPARC64-LABEL: test_extend32: | |
| ; SPARC64: ! %bb.0: | |
| ; SPARC64-NEXT: save %sp, -176, %sp | |
| ; SPARC64-NEXT: call __extendhfsf2 | |
| ; SPARC64-NEXT: lduh [%i0], %o0 | |
| ; SPARC64-NEXT: ret | |
| ; SPARC64-NEXT: restore | |
| %val16 = load half, ptr %addr | |
| %val32 = fpext half %val16 to float | |
| ret float %val32 | |
| } | |
| define double @test_extend64(ptr %addr) nounwind { | |
| ; SPARC32-LABEL: test_extend64: | |
| ; SPARC32: ! %bb.0: | |
| ; SPARC32-NEXT: save %sp, -96, %sp | |
| ; SPARC32-NEXT: call __extendhfsf2 | |
| ; SPARC32-NEXT: lduh [%i0], %o0 | |
| ; SPARC32-NEXT: fstod %f0, %f0 | |
| ; SPARC32-NEXT: ret | |
| ; SPARC32-NEXT: restore | |
| ; | |
| ; SPARC64-LABEL: test_extend64: | |
| ; SPARC64: ! %bb.0: | |
| ; SPARC64-NEXT: save %sp, -176, %sp | |
| ; SPARC64-NEXT: call __extendhfsf2 | |
| ; SPARC64-NEXT: lduh [%i0], %o0 | |
| ; SPARC64-NEXT: fstod %f0, %f0 | |
| ; SPARC64-NEXT: ret | |
| ; SPARC64-NEXT: restore | |
| %val16 = load half, ptr %addr | |
| %val32 = fpext half %val16 to double | |
| ret double %val32 | |
| } | |
| define void @test_trunc32(float %in, ptr %addr) nounwind { | |
| ; SPARC32-LABEL: test_trunc32: | |
| ; SPARC32: ! %bb.0: | |
| ; SPARC32-NEXT: save %sp, -96, %sp | |
| ; SPARC32-NEXT: call __truncsfhf2 | |
| ; SPARC32-NEXT: mov %i0, %o0 | |
| ; SPARC32-NEXT: sth %o0, [%i1] | |
| ; SPARC32-NEXT: ret | |
| ; SPARC32-NEXT: restore | |
| ; | |
| ; SPARC64-LABEL: test_trunc32: | |
| ; SPARC64: ! %bb.0: | |
| ; SPARC64-NEXT: save %sp, -176, %sp | |
| ; SPARC64-NEXT: call __truncsfhf2 | |
| ; SPARC64-NEXT: nop | |
| ; SPARC64-NEXT: sth %o0, [%i1] | |
| ; SPARC64-NEXT: ret | |
| ; SPARC64-NEXT: restore | |
| %val16 = fptrunc float %in to half | |
| store half %val16, ptr %addr | |
| ret void | |
| } | |
| define void @test_trunc64(double %in, ptr %addr) nounwind { | |
| ; SPARC32-LABEL: test_trunc64: | |
| ; SPARC32: ! %bb.0: | |
| ; SPARC32-NEXT: save %sp, -112, %sp | |
| ; SPARC32-NEXT: ! kill: def $i1 killed $i1 killed $i0_i1 def $i0_i1 | |
| ; SPARC32-NEXT: ! kill: def $i0 killed $i0 killed $i0_i1 def $i0_i1 | |
| ; SPARC32-NEXT: std %i0, [%fp+-8] | |
| ; SPARC32-NEXT: ldd [%fp+-8], %f0 | |
| ; SPARC32-NEXT: std %f0, [%fp+-16] | |
| ; SPARC32-NEXT: call __truncdfhf2 | |
| ; SPARC32-NEXT: ldd [%fp+-16], %o0 | |
| ; SPARC32-NEXT: sth %o0, [%i2] | |
| ; SPARC32-NEXT: ret | |
| ; SPARC32-NEXT: restore | |
| ; | |
| ; SPARC64-LABEL: test_trunc64: | |
| ; SPARC64: ! %bb.0: | |
| ; SPARC64-NEXT: save %sp, -176, %sp | |
| ; SPARC64-NEXT: call __truncdfhf2 | |
| ; SPARC64-NEXT: nop | |
| ; SPARC64-NEXT: sth %o0, [%i1] | |
| ; SPARC64-NEXT: ret | |
| ; SPARC64-NEXT: restore | |
| %val16 = fptrunc double %in to half | |
| store half %val16, ptr %addr | |
| ret void | |
| } | |
| define i64 @test_fptosi_i64(ptr %p) nounwind { | |
| ; SPARC32-LABEL: test_fptosi_i64: | |
| ; SPARC32: ! %bb.0: | |
| ; SPARC32-NEXT: save %sp, -96, %sp | |
| ; SPARC32-NEXT: call __extendhfsf2 | |
| ; SPARC32-NEXT: lduh [%i0], %o0 | |
| ; SPARC32-NEXT: st %f0, [%fp+-4] | |
| ; SPARC32-NEXT: call __fixsfdi | |
| ; SPARC32-NEXT: ld [%fp+-4], %o0 | |
| ; SPARC32-NEXT: mov %o0, %i0 | |
| ; SPARC32-NEXT: ret | |
| ; SPARC32-NEXT: restore %g0, %o1, %o1 | |
| ; | |
| ; SPARC64-LABEL: test_fptosi_i64: | |
| ; SPARC64: ! %bb.0: | |
| ; SPARC64-NEXT: save %sp, -192, %sp | |
| ; SPARC64-NEXT: call __extendhfsf2 | |
| ; SPARC64-NEXT: lduh [%i0], %o0 | |
| ; SPARC64-NEXT: fstox %f0, %f0 | |
| ; SPARC64-NEXT: std %f0, [%fp+2039] | |
| ; SPARC64-NEXT: ldx [%fp+2039], %i0 | |
| ; SPARC64-NEXT: ret | |
| ; SPARC64-NEXT: restore | |
| %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 { | |
| ; SPARC32-LABEL: test_sitofp_i64: | |
| ; SPARC32: ! %bb.0: | |
| ; SPARC32-NEXT: save %sp, -96, %sp | |
| ; SPARC32-NEXT: mov %i1, %o1 | |
| ; SPARC32-NEXT: call __floatdisf | |
| ; SPARC32-NEXT: mov %i0, %o0 | |
| ; SPARC32-NEXT: st %f0, [%fp+-4] | |
| ; SPARC32-NEXT: call __truncsfhf2 | |
| ; SPARC32-NEXT: ld [%fp+-4], %o0 | |
| ; SPARC32-NEXT: sth %o0, [%i2] | |
| ; SPARC32-NEXT: ret | |
| ; SPARC32-NEXT: restore | |
| ; | |
| ; SPARC64-LABEL: test_sitofp_i64: | |
| ; SPARC64: ! %bb.0: | |
| ; SPARC64-NEXT: save %sp, -192, %sp | |
| ; SPARC64-NEXT: stx %i0, [%fp+2039] | |
| ; SPARC64-NEXT: ldd [%fp+2039], %f0 | |
| ; SPARC64-NEXT: call __truncsfhf2 | |
| ; SPARC64-NEXT: fxtos %f0, %f1 | |
| ; SPARC64-NEXT: sth %o0, [%i1] | |
| ; SPARC64-NEXT: ret | |
| ; SPARC64-NEXT: restore | |
| %r = sitofp i64 %a to half | |
| store half %r, ptr %p | |
| ret void | |
| } | |
| define i64 @test_fptoui_i64(ptr %p) nounwind { | |
| ; SPARC32-LABEL: test_fptoui_i64: | |
| ; SPARC32: ! %bb.0: | |
| ; SPARC32-NEXT: save %sp, -96, %sp | |
| ; SPARC32-NEXT: call __extendhfsf2 | |
| ; SPARC32-NEXT: lduh [%i0], %o0 | |
| ; SPARC32-NEXT: st %f0, [%fp+-4] | |
| ; SPARC32-NEXT: call __fixunssfdi | |
| ; SPARC32-NEXT: ld [%fp+-4], %o0 | |
| ; SPARC32-NEXT: mov %o0, %i0 | |
| ; SPARC32-NEXT: ret | |
| ; SPARC32-NEXT: restore %g0, %o1, %o1 | |
| ; | |
| ; SPARC64-LABEL: test_fptoui_i64: | |
| ; SPARC64: ! %bb.0: | |
| ; SPARC64-NEXT: save %sp, -192, %sp | |
| ; SPARC64-NEXT: call __extendhfsf2 | |
| ; SPARC64-NEXT: lduh [%i0], %o0 | |
| ; SPARC64-NEXT: sethi %h44(.LCPI13_0), %i0 | |
| ; SPARC64-NEXT: add %i0, %m44(.LCPI13_0), %i0 | |
| ; SPARC64-NEXT: sllx %i0, 12, %i0 | |
| ; SPARC64-NEXT: ld [%i0+%l44(.LCPI13_0)], %f1 | |
| ; SPARC64-NEXT: fsubs %f0, %f1, %f2 | |
| ; SPARC64-NEXT: fstox %f2, %f2 | |
| ; SPARC64-NEXT: std %f2, [%fp+2031] | |
| ; SPARC64-NEXT: fstox %f0, %f2 | |
| ; SPARC64-NEXT: std %f2, [%fp+2039] | |
| ; SPARC64-NEXT: ldx [%fp+2031], %i0 | |
| ; SPARC64-NEXT: sethi 0, %i1 | |
| ; SPARC64-NEXT: or %i1, 0, %i1 | |
| ; SPARC64-NEXT: sethi 2097152, %i2 | |
| ; SPARC64-NEXT: or %i2, 0, %i2 | |
| ; SPARC64-NEXT: sllx %i2, 32, %i2 | |
| ; SPARC64-NEXT: ldx [%fp+2039], %i3 | |
| ; SPARC64-NEXT: or %i2, %i1, %i1 | |
| ; SPARC64-NEXT: xor %i0, %i1, %i0 | |
| ; SPARC64-NEXT: fcmps %fcc0, %f0, %f1 | |
| ; SPARC64-NEXT: movl %fcc0, %i3, %i0 | |
| ; SPARC64-NEXT: ret | |
| ; SPARC64-NEXT: restore | |
| %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 { | |
| ; SPARC32-LABEL: test_uitofp_i64: | |
| ; SPARC32: ! %bb.0: | |
| ; SPARC32-NEXT: save %sp, -96, %sp | |
| ; SPARC32-NEXT: mov %i1, %o1 | |
| ; SPARC32-NEXT: call __floatundisf | |
| ; SPARC32-NEXT: mov %i0, %o0 | |
| ; SPARC32-NEXT: st %f0, [%fp+-4] | |
| ; SPARC32-NEXT: call __truncsfhf2 | |
| ; SPARC32-NEXT: ld [%fp+-4], %o0 | |
| ; SPARC32-NEXT: sth %o0, [%i2] | |
| ; SPARC32-NEXT: ret | |
| ; SPARC32-NEXT: restore | |
| ; | |
| ; SPARC64-LABEL: test_uitofp_i64: | |
| ; SPARC64: ! %bb.0: | |
| ; SPARC64-NEXT: save %sp, -192, %sp | |
| ; SPARC64-NEXT: stx %i0, [%fp+2031] | |
| ; SPARC64-NEXT: srlx %i0, 1, %i2 | |
| ; SPARC64-NEXT: and %i0, 1, %i3 | |
| ; SPARC64-NEXT: or %i3, %i2, %i2 | |
| ; SPARC64-NEXT: stx %i2, [%fp+2039] | |
| ; SPARC64-NEXT: ldd [%fp+2031], %f0 | |
| ; SPARC64-NEXT: ldd [%fp+2039], %f2 | |
| ; SPARC64-NEXT: fxtos %f0, %f1 | |
| ; SPARC64-NEXT: fxtos %f2, %f0 | |
| ; SPARC64-NEXT: fadds %f0, %f0, %f0 | |
| ; SPARC64-NEXT: call __truncsfhf2 | |
| ; SPARC64-NEXT: fmovrslz %i0, %f0, %f1 | |
| ; SPARC64-NEXT: sth %o0, [%i1] | |
| ; SPARC64-NEXT: ret | |
| ; SPARC64-NEXT: restore | |
| %r = uitofp i64 %a to half | |
| store half %r, ptr %p | |
| ret void | |
| } | |
| define <4 x float> @test_extend32_vec4(ptr %p) nounwind { | |
| ; SPARC32-LABEL: test_extend32_vec4: | |
| ; SPARC32: ! %bb.0: | |
| ; SPARC32-NEXT: save %sp, -104, %sp | |
| ; SPARC32-NEXT: call __extendhfsf2 | |
| ; SPARC32-NEXT: lduh [%i0], %o0 | |
| ; SPARC32-NEXT: st %f0, [%fp+-4] ! 4-byte Folded Spill | |
| ; SPARC32-NEXT: call __extendhfsf2 | |
| ; SPARC32-NEXT: lduh [%i0+2], %o0 | |
| ; SPARC32-NEXT: st %f0, [%fp+-8] ! 4-byte Folded Spill | |
| ; SPARC32-NEXT: call __extendhfsf2 | |
| ; SPARC32-NEXT: lduh [%i0+4], %o0 | |
| ; SPARC32-NEXT: st %f0, [%fp+-12] ! 4-byte Folded Spill | |
| ; SPARC32-NEXT: call __extendhfsf2 | |
| ; SPARC32-NEXT: lduh [%i0+6], %o0 | |
| ; SPARC32-NEXT: fmovs %f0, %f3 | |
| ; SPARC32-NEXT: ld [%fp+-4], %f0 ! 4-byte Folded Reload | |
| ; SPARC32-NEXT: ld [%fp+-8], %f1 ! 4-byte Folded Reload | |
| ; SPARC32-NEXT: ld [%fp+-12], %f2 ! 4-byte Folded Reload | |
| ; SPARC32-NEXT: ret | |
| ; SPARC32-NEXT: restore | |
| ; | |
| ; SPARC64-LABEL: test_extend32_vec4: | |
| ; SPARC64: ! %bb.0: | |
| ; SPARC64-NEXT: save %sp, -192, %sp | |
| ; SPARC64-NEXT: call __extendhfsf2 | |
| ; SPARC64-NEXT: lduh [%i0], %o0 | |
| ; SPARC64-NEXT: st %f0, [%fp+2043] ! 4-byte Folded Spill | |
| ; SPARC64-NEXT: call __extendhfsf2 | |
| ; SPARC64-NEXT: lduh [%i0+2], %o0 | |
| ; SPARC64-NEXT: st %f0, [%fp+2039] ! 4-byte Folded Spill | |
| ; SPARC64-NEXT: call __extendhfsf2 | |
| ; SPARC64-NEXT: lduh [%i0+4], %o0 | |
| ; SPARC64-NEXT: st %f0, [%fp+2035] ! 4-byte Folded Spill | |
| ; SPARC64-NEXT: call __extendhfsf2 | |
| ; SPARC64-NEXT: lduh [%i0+6], %o0 | |
| ; SPARC64-NEXT: fmovs %f0, %f3 | |
| ; SPARC64-NEXT: ld [%fp+2043], %f0 ! 4-byte Folded Reload | |
| ; SPARC64-NEXT: ld [%fp+2039], %f1 ! 4-byte Folded Reload | |
| ; SPARC64-NEXT: ld [%fp+2035], %f2 ! 4-byte Folded Reload | |
| ; SPARC64-NEXT: ret | |
| ; SPARC64-NEXT: restore | |
| %a = load <4 x half>, ptr %p, align 8 | |
| %b = fpext <4 x half> %a to <4 x float> | |
| ret <4 x float> %b | |
| } | |
| define <4 x double> @test_extend64_vec4(ptr %p) nounwind { | |
| ; SPARC32-LABEL: test_extend64_vec4: | |
| ; SPARC32: ! %bb.0: | |
| ; SPARC32-NEXT: save %sp, -120, %sp | |
| ; SPARC32-NEXT: ld [%fp+64], %i1 | |
| ; SPARC32-NEXT: call __extendhfsf2 | |
| ; SPARC32-NEXT: lduh [%i0+4], %o0 | |
| ; SPARC32-NEXT: st %f0, [%fp+-8] ! 4-byte Folded Spill | |
| ; SPARC32-NEXT: call __extendhfsf2 | |
| ; SPARC32-NEXT: lduh [%i0+2], %o0 | |
| ; SPARC32-NEXT: st %f0, [%fp+-16] ! 4-byte Folded Spill | |
| ; SPARC32-NEXT: call __extendhfsf2 | |
| ; SPARC32-NEXT: lduh [%i0], %o0 | |
| ; SPARC32-NEXT: lduh [%i0+6], %o0 | |
| ; SPARC32-NEXT: fstod %f0, %f0 | |
| ; SPARC32-NEXT: std %f0, [%fp+-24] ! 8-byte Folded Spill | |
| ; SPARC32-NEXT: ld [%fp+-16], %f0 ! 4-byte Folded Reload | |
| ; SPARC32-NEXT: fstod %f0, %f0 | |
| ; SPARC32-NEXT: std %f0, [%fp+-16] ! 8-byte Folded Spill | |
| ; SPARC32-NEXT: ld [%fp+-8], %f0 ! 4-byte Folded Reload | |
| ; SPARC32-NEXT: fstod %f0, %f0 | |
| ; SPARC32-NEXT: call __extendhfsf2 | |
| ; SPARC32-NEXT: std %f0, [%fp+-8] | |
| ; SPARC32-NEXT: fstod %f0, %f0 | |
| ; SPARC32-NEXT: std %f0, [%i1+24] | |
| ; SPARC32-NEXT: ldd [%fp+-8], %f0 ! 8-byte Folded Reload | |
| ; SPARC32-NEXT: std %f0, [%i1+16] | |
| ; SPARC32-NEXT: ldd [%fp+-16], %f0 ! 8-byte Folded Reload | |
| ; SPARC32-NEXT: std %f0, [%i1+8] | |
| ; SPARC32-NEXT: ldd [%fp+-24], %f0 ! 8-byte Folded Reload | |
| ; SPARC32-NEXT: std %f0, [%i1] | |
| ; SPARC32-NEXT: ret | |
| ; SPARC32-NEXT: restore | |
| ; | |
| ; SPARC64-LABEL: test_extend64_vec4: | |
| ; SPARC64: ! %bb.0: | |
| ; SPARC64-NEXT: save %sp, -208, %sp | |
| ; SPARC64-NEXT: call __extendhfsf2 | |
| ; SPARC64-NEXT: lduh [%i0], %o0 | |
| ; SPARC64-NEXT: fstod %f0, %f0 | |
| ; SPARC64-NEXT: std %f0, [%fp+2039] ! 8-byte Folded Spill | |
| ; SPARC64-NEXT: call __extendhfsf2 | |
| ; SPARC64-NEXT: lduh [%i0+2], %o0 | |
| ; SPARC64-NEXT: fstod %f0, %f0 | |
| ; SPARC64-NEXT: std %f0, [%fp+2031] ! 8-byte Folded Spill | |
| ; SPARC64-NEXT: call __extendhfsf2 | |
| ; SPARC64-NEXT: lduh [%i0+4], %o0 | |
| ; SPARC64-NEXT: fstod %f0, %f0 | |
| ; SPARC64-NEXT: std %f0, [%fp+2023] ! 8-byte Folded Spill | |
| ; SPARC64-NEXT: call __extendhfsf2 | |
| ; SPARC64-NEXT: lduh [%i0+6], %o0 | |
| ; SPARC64-NEXT: fstod %f0, %f6 | |
| ; SPARC64-NEXT: ldd [%fp+2039], %f0 ! 8-byte Folded Reload | |
| ; SPARC64-NEXT: ldd [%fp+2031], %f2 ! 8-byte Folded Reload | |
| ; SPARC64-NEXT: ldd [%fp+2023], %f4 ! 8-byte Folded Reload | |
| ; SPARC64-NEXT: ret | |
| ; SPARC64-NEXT: restore | |
| %a = load <4 x half>, ptr %p, align 8 | |
| %b = fpext <4 x half> %a to <4 x double> | |
| ret <4 x double> %b | |
| } | |
| define void @test_trunc32_vec4(<4 x float> %a, ptr %p) nounwind { | |
| ; SPARC32-LABEL: test_trunc32_vec4: | |
| ; SPARC32: ! %bb.0: | |
| ; SPARC32-NEXT: save %sp, -96, %sp | |
| ; SPARC32-NEXT: call __truncsfhf2 | |
| ; SPARC32-NEXT: mov %i0, %o0 | |
| ; SPARC32-NEXT: mov %o0, %i0 | |
| ; SPARC32-NEXT: call __truncsfhf2 | |
| ; SPARC32-NEXT: mov %i1, %o0 | |
| ; SPARC32-NEXT: mov %o0, %i1 | |
| ; SPARC32-NEXT: call __truncsfhf2 | |
| ; SPARC32-NEXT: mov %i2, %o0 | |
| ; SPARC32-NEXT: mov %o0, %i2 | |
| ; SPARC32-NEXT: call __truncsfhf2 | |
| ; SPARC32-NEXT: mov %i3, %o0 | |
| ; SPARC32-NEXT: sth %o0, [%i4+6] | |
| ; SPARC32-NEXT: sth %i2, [%i4+4] | |
| ; SPARC32-NEXT: sth %i1, [%i4+2] | |
| ; SPARC32-NEXT: sth %i0, [%i4] | |
| ; SPARC32-NEXT: ret | |
| ; SPARC32-NEXT: restore | |
| ; | |
| ; SPARC64-LABEL: test_trunc32_vec4: | |
| ; SPARC64: ! %bb.0: | |
| ; SPARC64-NEXT: save %sp, -192, %sp | |
| ; SPARC64-NEXT: st %f7, [%fp+2043] ! 4-byte Folded Spill | |
| ; SPARC64-NEXT: st %f5, [%fp+2039] ! 4-byte Folded Spill | |
| ; SPARC64-NEXT: call __truncsfhf2 | |
| ; SPARC64-NEXT: st %f3, [%fp+2035] | |
| ; SPARC64-NEXT: mov %o0, %i0 | |
| ; SPARC64-NEXT: call __truncsfhf2 | |
| ; SPARC64-NEXT: ld [%fp+2035], %f1 | |
| ; SPARC64-NEXT: mov %o0, %i1 | |
| ; SPARC64-NEXT: call __truncsfhf2 | |
| ; SPARC64-NEXT: ld [%fp+2039], %f1 | |
| ; SPARC64-NEXT: mov %o0, %i2 | |
| ; SPARC64-NEXT: call __truncsfhf2 | |
| ; SPARC64-NEXT: ld [%fp+2043], %f1 | |
| ; SPARC64-NEXT: sth %o0, [%i4+6] | |
| ; SPARC64-NEXT: sth %i2, [%i4+4] | |
| ; SPARC64-NEXT: sth %i1, [%i4+2] | |
| ; SPARC64-NEXT: sth %i0, [%i4] | |
| ; SPARC64-NEXT: ret | |
| ; SPARC64-NEXT: restore | |
| %v = fptrunc <4 x float> %a to <4 x half> | |
| store <4 x half> %v, ptr %p | |
| ret void | |
| } | |
| define void @test_trunc64_vec4(<4 x double> %a, ptr %p) nounwind { | |
| ; SPARC32-LABEL: test_trunc64_vec4: | |
| ; SPARC32: ! %bb.0: | |
| ; SPARC32-NEXT: save %sp, -160, %sp | |
| ; SPARC32-NEXT: ld [%fp+92], %g2 | |
| ; SPARC32-NEXT: ld [%fp+96], %g3 | |
| ; SPARC32-NEXT: ! kill: def $i5 killed $i5 killed $i4_i5 def $i4_i5 | |
| ; SPARC32-NEXT: ! kill: def $i3 killed $i3 killed $i2_i3 def $i2_i3 | |
| ; SPARC32-NEXT: ! kill: def $i1 killed $i1 killed $i0_i1 def $i0_i1 | |
| ; SPARC32-NEXT: std %g2, [%fp+-32] | |
| ; SPARC32-NEXT: ! kill: def $i4 killed $i4 killed $i4_i5 def $i4_i5 | |
| ; SPARC32-NEXT: std %i4, [%fp+-24] | |
| ; SPARC32-NEXT: ! kill: def $i2 killed $i2 killed $i2_i3 def $i2_i3 | |
| ; SPARC32-NEXT: std %i2, [%fp+-16] | |
| ; SPARC32-NEXT: ! kill: def $i0 killed $i0 killed $i0_i1 def $i0_i1 | |
| ; SPARC32-NEXT: std %i0, [%fp+-8] | |
| ; SPARC32-NEXT: ld [%fp+100], %i3 | |
| ; SPARC32-NEXT: ldd [%fp+-8], %f0 | |
| ; SPARC32-NEXT: ldd [%fp+-16], %f2 | |
| ; SPARC32-NEXT: ldd [%fp+-24], %f4 | |
| ; SPARC32-NEXT: ldd [%fp+-32], %f6 | |
| ; SPARC32-NEXT: std %f0, [%fp+-40] | |
| ; SPARC32-NEXT: std %f2, [%fp+-48] | |
| ; SPARC32-NEXT: std %f4, [%fp+-56] | |
| ; SPARC32-NEXT: std %f6, [%fp+-64] | |
| ; SPARC32-NEXT: call __truncdfhf2 | |
| ; SPARC32-NEXT: ldd [%fp+-40], %o0 | |
| ; SPARC32-NEXT: mov %o0, %i0 | |
| ; SPARC32-NEXT: call __truncdfhf2 | |
| ; SPARC32-NEXT: ldd [%fp+-48], %o0 | |
| ; SPARC32-NEXT: mov %o0, %i1 | |
| ; SPARC32-NEXT: call __truncdfhf2 | |
| ; SPARC32-NEXT: ldd [%fp+-56], %o0 | |
| ; SPARC32-NEXT: mov %o0, %i2 | |
| ; SPARC32-NEXT: call __truncdfhf2 | |
| ; SPARC32-NEXT: ldd [%fp+-64], %o0 | |
| ; SPARC32-NEXT: sth %o0, [%i3+6] | |
| ; SPARC32-NEXT: sth %i2, [%i3+4] | |
| ; SPARC32-NEXT: sth %i1, [%i3+2] | |
| ; SPARC32-NEXT: sth %i0, [%i3] | |
| ; SPARC32-NEXT: ret | |
| ; SPARC32-NEXT: restore | |
| ; | |
| ; SPARC64-LABEL: test_trunc64_vec4: | |
| ; SPARC64: ! %bb.0: | |
| ; SPARC64-NEXT: save %sp, -208, %sp | |
| ; SPARC64-NEXT: std %f6, [%fp+2039] ! 8-byte Folded Spill | |
| ; SPARC64-NEXT: std %f4, [%fp+2031] ! 8-byte Folded Spill | |
| ; SPARC64-NEXT: call __truncdfhf2 | |
| ; SPARC64-NEXT: std %f2, [%fp+2023] | |
| ; SPARC64-NEXT: mov %o0, %i0 | |
| ; SPARC64-NEXT: call __truncdfhf2 | |
| ; SPARC64-NEXT: ldd [%fp+2023], %f0 | |
| ; SPARC64-NEXT: mov %o0, %i1 | |
| ; SPARC64-NEXT: call __truncdfhf2 | |
| ; SPARC64-NEXT: ldd [%fp+2031], %f0 | |
| ; SPARC64-NEXT: mov %o0, %i2 | |
| ; SPARC64-NEXT: call __truncdfhf2 | |
| ; SPARC64-NEXT: ldd [%fp+2039], %f0 | |
| ; SPARC64-NEXT: sth %o0, [%i4+6] | |
| ; SPARC64-NEXT: sth %i2, [%i4+4] | |
| ; SPARC64-NEXT: sth %i1, [%i4+2] | |
| ; SPARC64-NEXT: sth %i0, [%i4] | |
| ; SPARC64-NEXT: ret | |
| ; SPARC64-NEXT: restore | |
| %v = fptrunc <4 x double> %a to <4 x half> | |
| store <4 x half> %v, ptr %p | |
| ret void | |
| } | |
| define float @test_sitofp_fadd_i32(i32 %a, ptr %b) nounwind { | |
| ; SPARC32-LABEL: test_sitofp_fadd_i32: | |
| ; SPARC32: ! %bb.0: | |
| ; SPARC32-NEXT: save %sp, -112, %sp | |
| ; SPARC32-NEXT: lduh [%i1], %i1 | |
| ; SPARC32-NEXT: st %i0, [%fp+-4] | |
| ; SPARC32-NEXT: ld [%fp+-4], %f0 | |
| ; SPARC32-NEXT: fitos %f0, %f0 | |
| ; SPARC32-NEXT: st %f0, [%fp+-8] | |
| ; SPARC32-NEXT: call __truncsfhf2 | |
| ; SPARC32-NEXT: ld [%fp+-8], %o0 | |
| ; SPARC32-NEXT: call __extendhfsf2 | |
| ; SPARC32-NEXT: nop | |
| ; SPARC32-NEXT: st %f0, [%fp+-16] ! 4-byte Folded Spill | |
| ; SPARC32-NEXT: call __extendhfsf2 | |
| ; SPARC32-NEXT: mov %i1, %o0 | |
| ; SPARC32-NEXT: ld [%fp+-16], %f1 ! 4-byte Folded Reload | |
| ; SPARC32-NEXT: fadds %f0, %f1, %f0 | |
| ; SPARC32-NEXT: st %f0, [%fp+-12] | |
| ; SPARC32-NEXT: call __truncsfhf2 | |
| ; SPARC32-NEXT: ld [%fp+-12], %o0 | |
| ; SPARC32-NEXT: call __extendhfsf2 | |
| ; SPARC32-NEXT: nop | |
| ; SPARC32-NEXT: ret | |
| ; SPARC32-NEXT: restore | |
| ; | |
| ; SPARC64-LABEL: test_sitofp_fadd_i32: | |
| ; SPARC64: ! %bb.0: | |
| ; SPARC64-NEXT: save %sp, -192, %sp | |
| ; SPARC64-NEXT: lduh [%i1], %i1 | |
| ; SPARC64-NEXT: st %i0, [%fp+2043] | |
| ; SPARC64-NEXT: ld [%fp+2043], %f0 | |
| ; SPARC64-NEXT: call __truncsfhf2 | |
| ; SPARC64-NEXT: fitos %f0, %f1 | |
| ; SPARC64-NEXT: call __extendhfsf2 | |
| ; SPARC64-NEXT: nop | |
| ; SPARC64-NEXT: st %f0, [%fp+2039] ! 4-byte Folded Spill | |
| ; SPARC64-NEXT: call __extendhfsf2 | |
| ; SPARC64-NEXT: mov %i1, %o0 | |
| ; SPARC64-NEXT: ld [%fp+2039], %f1 ! 4-byte Folded Reload | |
| ; SPARC64-NEXT: call __truncsfhf2 | |
| ; SPARC64-NEXT: fadds %f0, %f1, %f1 | |
| ; SPARC64-NEXT: call __extendhfsf2 | |
| ; SPARC64-NEXT: nop | |
| ; SPARC64-NEXT: ret | |
| ; SPARC64-NEXT: restore | |
| %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 @PR40273(half) nounwind { | |
| ; V8-LABEL: PR40273: | |
| ; V8: ! %bb.0: | |
| ; V8-NEXT: save %sp, -96, %sp | |
| ; V8-NEXT: call __extendhfsf2 | |
| ; V8-NEXT: mov %i0, %o0 | |
| ; V8-NEXT: sethi %hi(.LCPI20_0), %i0 | |
| ; V8-NEXT: ld [%i0+%lo(.LCPI20_0)], %f1 | |
| ; V8-NEXT: fcmps %f0, %f1 | |
| ; V8-NEXT: nop | |
| ; V8-NEXT: fbne .LBB20_2 | |
| ; V8-NEXT: nop | |
| ; V8-NEXT: ! %bb.1: | |
| ; V8-NEXT: ret | |
| ; V8-NEXT: restore %g0, %g0, %o0 | |
| ; V8-NEXT: .LBB20_2: | |
| ; V8-NEXT: sethi 15, %i0 | |
| ; V8-NEXT: ret | |
| ; V8-NEXT: restore | |
| ; | |
| ; V9-LABEL: PR40273: | |
| ; V9: ! %bb.0: | |
| ; V9-NEXT: save %sp, -96, %sp | |
| ; V9-NEXT: call __extendhfsf2 | |
| ; V9-NEXT: mov %i0, %o0 | |
| ; V9-NEXT: sethi %hi(.LCPI20_0), %i0 | |
| ; V9-NEXT: ld [%i0+%lo(.LCPI20_0)], %f1 | |
| ; V9-NEXT: mov %g0, %i0 | |
| ; V9-NEXT: sethi 15, %i1 | |
| ; V9-NEXT: fcmps %fcc0, %f0, %f1 | |
| ; V9-NEXT: movne %fcc0, %i1, %i0 | |
| ; V9-NEXT: ret | |
| ; V9-NEXT: restore | |
| ; | |
| ; SPARC64-LABEL: PR40273: | |
| ; SPARC64: ! %bb.0: | |
| ; SPARC64-NEXT: save %sp, -176, %sp | |
| ; SPARC64-NEXT: call __extendhfsf2 | |
| ; SPARC64-NEXT: srl %i0, 0, %o0 | |
| ; SPARC64-NEXT: sethi %h44(.LCPI20_0), %i0 | |
| ; SPARC64-NEXT: add %i0, %m44(.LCPI20_0), %i0 | |
| ; SPARC64-NEXT: sllx %i0, 12, %i0 | |
| ; SPARC64-NEXT: ld [%i0+%l44(.LCPI20_0)], %f1 | |
| ; SPARC64-NEXT: mov %g0, %i0 | |
| ; SPARC64-NEXT: sethi 15, %i1 | |
| ; SPARC64-NEXT: fcmps %fcc0, %f0, %f1 | |
| ; SPARC64-NEXT: movne %fcc0, %i1, %i0 | |
| ; SPARC64-NEXT: ret | |
| ; SPARC64-NEXT: restore | |
| %2 = fcmp une half %0, 0xH0000 | |
| %3 = uitofp i1 %2 to half | |
| ret half %3 | |
| } | |
| define half @fabs(half %x) nounwind { | |
| ; SPARC32-LABEL: fabs: | |
| ; SPARC32: ! %bb.0: | |
| ; SPARC32-NEXT: sethi 4194272, %o1 | |
| ; SPARC32-NEXT: retl | |
| ; SPARC32-NEXT: andn %o0, %o1, %o0 | |
| ; | |
| ; SPARC64-LABEL: fabs: | |
| ; SPARC64: ! %bb.0: | |
| ; SPARC64-NEXT: sethi 31, %o1 | |
| ; SPARC64-NEXT: or %o1, 1023, %o1 | |
| ; SPARC64-NEXT: retl | |
| ; SPARC64-NEXT: and %o0, %o1, %o0 | |
| %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: sethi 4194272, %o2 | |
| ; CHECK-NEXT: and %o1, %o2, %o1 | |
| ; CHECK-NEXT: andn %o0, %o2, %o0 | |
| ; CHECK-NEXT: retl | |
| ; CHECK-NEXT: or %o0, %o1, %o0 | |
| %a = call half @llvm.copysign.f16(half %x, half %y) | |
| ret half %a | |
| } |