| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 | |
| ; RUN: llc -mtriple=xtensa -mcpu=esp32 < %s | FileCheck --check-prefix=CHECK-ESP32 %s | |
| ; RUN: llc -mtriple=xtensa -mcpu=esp32s2 < %s | FileCheck --check-prefix=CHECK-ESP32S2 %s | |
| target datalayout = "e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32" | |
| target triple = "xtensa" | |
| @x = global i16 12902 | |
| @y = global i16 0 | |
| @z = common global i16 0 | |
| define void @foo() nounwind { | |
| ; CHECK-ESP32-LABEL: foo: | |
| ; CHECK-ESP32: # %bb.0: # %entry | |
| ; CHECK-ESP32-NEXT: entry a1, 32 | |
| ; CHECK-ESP32-NEXT: l32r a6, .LCPI0_0 | |
| ; CHECK-ESP32-NEXT: l16ui a10, a6, 0 | |
| ; CHECK-ESP32-NEXT: l32r a8, .LCPI0_1 | |
| ; CHECK-ESP32-NEXT: callx8 a8 | |
| ; CHECK-ESP32-NEXT: or a7, a10, a10 | |
| ; CHECK-ESP32-NEXT: l32r a8, .LCPI0_2 | |
| ; CHECK-ESP32-NEXT: l16ui a10, a8, 0 | |
| ; CHECK-ESP32-NEXT: l32r a8, .LCPI0_3 | |
| ; CHECK-ESP32-NEXT: callx8 a8 | |
| ; CHECK-ESP32-NEXT: wfr f8, a10 | |
| ; CHECK-ESP32-NEXT: wfr f9, a7 | |
| ; CHECK-ESP32-NEXT: add.s f8, f9, f8 | |
| ; CHECK-ESP32-NEXT: rfr a10, f8 | |
| ; CHECK-ESP32-NEXT: l32r a8, .LCPI0_4 | |
| ; CHECK-ESP32-NEXT: callx8 a8 | |
| ; CHECK-ESP32-NEXT: s16i a10, a6, 0 | |
| ; CHECK-ESP32-NEXT: retw.n | |
| ; | |
| ; CHECK-ESP32S2-LABEL: foo: | |
| ; CHECK-ESP32S2: # %bb.0: # %entry | |
| ; CHECK-ESP32S2-NEXT: entry a1, 32 | |
| ; CHECK-ESP32S2-NEXT: l32r a6, .LCPI0_0 | |
| ; CHECK-ESP32S2-NEXT: l16ui a10, a6, 0 | |
| ; CHECK-ESP32S2-NEXT: l32r a8, .LCPI0_1 | |
| ; CHECK-ESP32S2-NEXT: callx8 a8 | |
| ; CHECK-ESP32S2-NEXT: or a7, a10, a10 | |
| ; CHECK-ESP32S2-NEXT: l32r a8, .LCPI0_2 | |
| ; CHECK-ESP32S2-NEXT: l16ui a10, a8, 0 | |
| ; CHECK-ESP32S2-NEXT: l32r a8, .LCPI0_3 | |
| ; CHECK-ESP32S2-NEXT: callx8 a8 | |
| ; CHECK-ESP32S2-NEXT: or a11, a10, a10 | |
| ; CHECK-ESP32S2-NEXT: l32r a8, .LCPI0_4 | |
| ; CHECK-ESP32S2-NEXT: or a10, a7, a7 | |
| ; CHECK-ESP32S2-NEXT: callx8 a8 | |
| ; CHECK-ESP32S2-NEXT: l32r a8, .LCPI0_5 | |
| ; CHECK-ESP32S2-NEXT: callx8 a8 | |
| ; CHECK-ESP32S2-NEXT: s16i a10, a6, 0 | |
| ; CHECK-ESP32S2-NEXT: retw.n | |
| entry: | |
| %fp16_v1 = load i16, ptr @x, align 2 | |
| %fp16_v2 = load i16, ptr @y, align 2 | |
| %f32_v1 = tail call float @llvm.convert.from.fp16.f32(i16 %fp16_v1) | |
| %f32_v2 = tail call float @llvm.convert.from.fp16.f32(i16 %fp16_v2) | |
| %f32_res = fadd float %f32_v1, %f32_v2 | |
| %fp16_res = tail call i16 @llvm.convert.to.fp16.f32(float %f32_res) | |
| store i16 %fp16_res, ptr @x, align 2 | |
| ret void | |
| } | |
| define double @test_from_fp16(i16 %in) { | |
| ; CHECK-ESP32-LABEL: test_from_fp16: | |
| ; CHECK-ESP32: .cfi_startproc | |
| ; CHECK-ESP32-NEXT: # %bb.0: | |
| ; CHECK-ESP32-NEXT: entry a1, 32 | |
| ; CHECK-ESP32-NEXT: .cfi_def_cfa_offset 32 | |
| ; CHECK-ESP32-NEXT: or a10, a2, a2 | |
| ; CHECK-ESP32-NEXT: l32r a8, .LCPI1_0 | |
| ; CHECK-ESP32-NEXT: callx8 a8 | |
| ; CHECK-ESP32-NEXT: l32r a8, .LCPI1_1 | |
| ; CHECK-ESP32-NEXT: callx8 a8 | |
| ; CHECK-ESP32-NEXT: or a2, a10, a10 | |
| ; CHECK-ESP32-NEXT: or a3, a11, a11 | |
| ; CHECK-ESP32-NEXT: retw.n | |
| ; | |
| ; CHECK-ESP32S2-LABEL: test_from_fp16: | |
| ; CHECK-ESP32S2: .cfi_startproc | |
| ; CHECK-ESP32S2-NEXT: # %bb.0: | |
| ; CHECK-ESP32S2-NEXT: entry a1, 32 | |
| ; CHECK-ESP32S2-NEXT: .cfi_def_cfa_offset 32 | |
| ; CHECK-ESP32S2-NEXT: l32r a8, .LCPI1_0 | |
| ; CHECK-ESP32S2-NEXT: and a10, a2, a8 | |
| ; CHECK-ESP32S2-NEXT: l32r a8, .LCPI1_1 | |
| ; CHECK-ESP32S2-NEXT: callx8 a8 | |
| ; CHECK-ESP32S2-NEXT: l32r a8, .LCPI1_2 | |
| ; CHECK-ESP32S2-NEXT: callx8 a8 | |
| ; CHECK-ESP32S2-NEXT: or a2, a10, a10 | |
| ; CHECK-ESP32S2-NEXT: or a3, a11, a11 | |
| ; CHECK-ESP32S2-NEXT: retw.n | |
| %val = call double @llvm.convert.from.fp16.f64(i16 %in) | |
| ret double %val | |
| } | |
| define i16 @test_to_fp16(double %in) { | |
| ; CHECK-ESP32-LABEL: test_to_fp16: | |
| ; CHECK-ESP32: .cfi_startproc | |
| ; CHECK-ESP32-NEXT: # %bb.0: | |
| ; CHECK-ESP32-NEXT: entry a1, 32 | |
| ; CHECK-ESP32-NEXT: .cfi_def_cfa_offset 32 | |
| ; CHECK-ESP32-NEXT: or a11, a3, a3 | |
| ; CHECK-ESP32-NEXT: or a10, a2, a2 | |
| ; CHECK-ESP32-NEXT: l32r a8, .LCPI2_0 | |
| ; CHECK-ESP32-NEXT: callx8 a8 | |
| ; CHECK-ESP32-NEXT: or a2, a10, a10 | |
| ; CHECK-ESP32-NEXT: retw.n | |
| ; | |
| ; CHECK-ESP32S2-LABEL: test_to_fp16: | |
| ; CHECK-ESP32S2: .cfi_startproc | |
| ; CHECK-ESP32S2-NEXT: # %bb.0: | |
| ; CHECK-ESP32S2-NEXT: entry a1, 32 | |
| ; CHECK-ESP32S2-NEXT: .cfi_def_cfa_offset 32 | |
| ; CHECK-ESP32S2-NEXT: or a11, a3, a3 | |
| ; CHECK-ESP32S2-NEXT: or a10, a2, a2 | |
| ; CHECK-ESP32S2-NEXT: l32r a8, .LCPI2_0 | |
| ; CHECK-ESP32S2-NEXT: callx8 a8 | |
| ; CHECK-ESP32S2-NEXT: or a2, a10, a10 | |
| ; CHECK-ESP32S2-NEXT: retw.n | |
| %val = call i16 @llvm.convert.to.fp16.f64(double %in) | |
| ret i16 %val | |
| } | |
| ; Function Attrs: nounwind | |
| define dso_local float @cvt(half %a) unnamed_addr #0 { | |
| ; CHECK-ESP32-LABEL: cvt: | |
| ; CHECK-ESP32: .cfi_startproc | |
| ; CHECK-ESP32-NEXT: # %bb.0: # %start | |
| ; CHECK-ESP32-NEXT: entry a1, 32 | |
| ; CHECK-ESP32-NEXT: .cfi_def_cfa_offset 32 | |
| ; CHECK-ESP32-NEXT: or a10, a2, a2 | |
| ; CHECK-ESP32-NEXT: l32r a8, .LCPI3_0 | |
| ; CHECK-ESP32-NEXT: callx8 a8 | |
| ; CHECK-ESP32-NEXT: or a2, a10, a10 | |
| ; CHECK-ESP32-NEXT: retw.n | |
| ; | |
| ; CHECK-ESP32S2-LABEL: cvt: | |
| ; CHECK-ESP32S2: .cfi_startproc | |
| ; CHECK-ESP32S2-NEXT: # %bb.0: # %start | |
| ; CHECK-ESP32S2-NEXT: entry a1, 32 | |
| ; CHECK-ESP32S2-NEXT: .cfi_def_cfa_offset 32 | |
| ; CHECK-ESP32S2-NEXT: l32r a8, .LCPI3_0 | |
| ; CHECK-ESP32S2-NEXT: and a10, a2, a8 | |
| ; CHECK-ESP32S2-NEXT: l32r a8, .LCPI3_1 | |
| ; CHECK-ESP32S2-NEXT: callx8 a8 | |
| ; CHECK-ESP32S2-NEXT: or a2, a10, a10 | |
| ; CHECK-ESP32S2-NEXT: retw.n | |
| start: | |
| %val = fpext half %a to float | |
| ret float %val | |
| } | |
| declare float @llvm.convert.from.fp16.f32(i16) nounwind readnone | |
| declare double @llvm.convert.from.fp16.f64(i16) nounwind readnone | |
| declare i16 @llvm.convert.to.fp16.f32(float) nounwind readnone | |
| declare i16 @llvm.convert.to.fp16.f64(double) nounwind readnone |