diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 180f0f2ef8e..ea9a48e2db8 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -1635,7 +1635,7 @@ public: LegalizeTypeAction LA = ValueTypeActions.getTypeAction(SVT); assert( - (LA == TypeLegal || + (LA == TypeLegal || LA == TypeSoftenFloat || ValueTypeActions.getTypeAction(NVT) != TypePromoteInteger) && "Promote may not follow Expand or Promote"); diff --git a/lib/CodeGen/TargetLoweringBase.cpp b/lib/CodeGen/TargetLoweringBase.cpp index efbcd339864..42cd4bf1fe1 100644 --- a/lib/CodeGen/TargetLoweringBase.cpp +++ b/lib/CodeGen/TargetLoweringBase.cpp @@ -1104,6 +1104,13 @@ void TargetLoweringBase::computeRegisterProperties() { } } + if (!isTypeLegal(MVT::f16)) { + NumRegistersForVT[MVT::f16] = NumRegistersForVT[MVT::i16]; + RegisterTypeForVT[MVT::f16] = RegisterTypeForVT[MVT::i16]; + TransformToType[MVT::f16] = MVT::i16; + ValueTypeActions.setTypeAction(MVT::f16, TypeSoftenFloat); + } + // Loop over all of the vector value types to see which need transformations. for (unsigned i = MVT::FIRST_VECTOR_VALUETYPE; i <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++i) { diff --git a/test/CodeGen/AArch64/half.ll b/test/CodeGen/AArch64/half.ll new file mode 100644 index 00000000000..735fc36952d --- /dev/null +++ b/test/CodeGen/AArch64/half.ll @@ -0,0 +1,26 @@ +; RUN: llc < %s -mtriple=arm64-apple-ios7.0 | FileCheck %s + +define void @test_load_store(half* %in, half* %out) { +; CHECK-LABEL: test_load_store: +; CHECK: ldr [[TMP:h[0-9]+]], [x0] +; CHECK: str [[TMP]], [x1] + %val = load half* %in + store half %val, half* %out + ret void +} + +define i16 @test_bitcast_from_half(half* %addr) { +; CHECK-LABEL: test_bitcast_from_half: +; CHECK: ldrh w0, [x0] + %val = load half* %addr + %val_int = bitcast half %val to i16 + ret i16 %val_int +} + +define void @test_bitcast_to_half(half* %addr, i16 %in) { +; CHECK-LABEL: test_bitcast_to_half: +; CHECK: strh w1, [x0] + %val_fp = bitcast i16 %in to half + store half %val_fp, half* %addr + ret void +} diff --git a/test/CodeGen/ARM/half.ll b/test/CodeGen/ARM/half.ll new file mode 100644 index 00000000000..72da1a514c6 --- /dev/null +++ b/test/CodeGen/ARM/half.ll @@ -0,0 +1,26 @@ +; RUN: llc < %s -mtriple=thumbv7s-apple-ios7.0 | FileCheck %s + +define void @test_load_store(half* %in, half* %out) { +; CHECK-LABEL: test_load_store: +; CHECK: ldrh [[TMP:r[0-9]+]], [r0] +; CHECK: strh [[TMP]], [r1] + %val = load half* %in + store half %val, half* %out + ret void +} + +define i16 @test_bitcast_from_half(half* %addr) { +; CHECK-LABEL: test_bitcast_from_half: +; CHECK: ldrh r0, [r0] + %val = load half* %addr + %val_int = bitcast half %val to i16 + ret i16 %val_int +} + +define void @test_bitcast_to_half(half* %addr, i16 %in) { +; CHECK-LABEL: test_bitcast_to_half: +; CHECK: strh r1, [r0] + %val_fp = bitcast i16 %in to half + store half %val_fp, half* %addr + ret void +} diff --git a/test/CodeGen/NVPTX/half.ll b/test/CodeGen/NVPTX/half.ll new file mode 100644 index 00000000000..ba18dc3c179 --- /dev/null +++ b/test/CodeGen/NVPTX/half.ll @@ -0,0 +1,30 @@ +; RUN: llc < %s -march=nvptx | FileCheck %s + +define void @test_load_store(half addrspace(1)* %in, half addrspace(1)* %out) { +; CHECK-LABEL: @test_load_store +; CHECK: ld.global.u16 [[TMP:%rs[0-9]+]], [{{%r[0-9]+}}] +; CHECK: st.global.u16 [{{%r[0-9]+}}], [[TMP]] + %val = load half addrspace(1)* %in + store half %val, half addrspace(1) * %out + ret void +} + +define void @test_bitcast_from_half(half addrspace(1)* %in, i16 addrspace(1)* %out) { +; CHECK-LABEL: @test_bitcast_from_half +; CHECK: ld.global.u16 [[TMP:%rs[0-9]+]], [{{%r[0-9]+}}] +; CHECK: st.global.u16 [{{%r[0-9]+}}], [[TMP]] + %val = load half addrspace(1) * %in + %val_int = bitcast half %val to i16 + store i16 %val_int, i16 addrspace(1)* %out + ret void +} + +define void @test_bitcast_to_half(half addrspace(1)* %out, i16 addrspace(1)* %in) { +; CHECK-LABEL: @test_bitcast_to_half +; CHECK: ld.global.u16 [[TMP:%rs[0-9]+]], [{{%r[0-9]+}}] +; CHECK: st.global.u16 [{{%r[0-9]+}}], [[TMP]] + %val = load i16 addrspace(1)* %in + %val_fp = bitcast i16 %val to half + store half %val_fp, half addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/half.ll b/test/CodeGen/R600/half.ll new file mode 100644 index 00000000000..58d3a1bdf47 --- /dev/null +++ b/test/CodeGen/R600/half.ll @@ -0,0 +1,30 @@ +; RUN: llc < %s -march=r600 -mcpu=SI | FileCheck %s + +define void @test_load_store(half addrspace(1)* %in, half addrspace(1)* %out) { +; CHECK-LABEL: @test_load_store +; CHECK: BUFFER_LOAD_USHORT [[TMP:v[0-9]+]] +; CHECK: BUFFER_STORE_SHORT [[TMP]] + %val = load half addrspace(1)* %in + store half %val, half addrspace(1) * %out + ret void +} + +define void @test_bitcast_from_half(half addrspace(1)* %in, i16 addrspace(1)* %out) { +; CHECK-LABEL: @test_bitcast_from_half +; CHECK: BUFFER_LOAD_USHORT [[TMP:v[0-9]+]] +; CHECK: BUFFER_STORE_SHORT [[TMP]] + %val = load half addrspace(1) * %in + %val_int = bitcast half %val to i16 + store i16 %val_int, i16 addrspace(1)* %out + ret void +} + +define void @test_bitcast_to_half(half addrspace(1)* %out, i16 addrspace(1)* %in) { +; CHECK-LABEL: @test_bitcast_to_half +; CHECK: BUFFER_LOAD_USHORT [[TMP:v[0-9]+]] +; CHECK: BUFFER_STORE_SHORT [[TMP]] + %val = load i16 addrspace(1)* %in + %val_fp = bitcast i16 %val to half + store half %val_fp, half addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/X86/half.ll b/test/CodeGen/X86/half.ll new file mode 100644 index 00000000000..150edaf99bd --- /dev/null +++ b/test/CodeGen/X86/half.ll @@ -0,0 +1,27 @@ +; RUN: llc < %s -march=x86-64 -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=-f16c | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-LIBCALL +; RUN: llc < %s -march=x86-64 -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=+f16c | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-F16C + +define void @test_load_store(half* %in, half* %out) { +; CHECK-LABEL: test_load_store: +; CHECK: movw (%rdi), [[TMP:%[a-z0-9]+]] +; CHECK: movw [[TMP]], (%rsi) + %val = load half* %in + store half %val, half* %out + ret void +} + +define i16 @test_bitcast_from_half(half* %addr) { +; CHECK-LABEL: test_bitcast_from_half: +; CHECK: movzwl (%rdi), %eax + %val = load half* %addr + %val_int = bitcast half %val to i16 + ret i16 %val_int +} + +define void @test_bitcast_to_half(half* %addr, i16 %in) { +; CHECK-LABEL: test_bitcast_to_half: +; CHECK: movw %si, (%rdi) + %val_fp = bitcast i16 %in to half + store half %val_fp, half* %addr + ret void +}