Index: lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- lib/Target/AArch64/AArch64ISelLowering.cpp +++ lib/Target/AArch64/AArch64ISelLowering.cpp @@ -582,7 +582,7 @@ setOperationAction(ISD::STORE, VT.getSimpleVT(), Promote); AddPromotedToType(ISD::STORE, VT.getSimpleVT(), MVT::v2i32); - } else if (VT == MVT::v2f64 || VT == MVT::v4f32) { + } else if (VT == MVT::v2f64 || VT == MVT::v4f32 || VT == MVT::v8f16) { setOperationAction(ISD::LOAD, VT.getSimpleVT(), Promote); AddPromotedToType(ISD::LOAD, VT.getSimpleVT(), MVT::v2i64); Index: lib/Target/AArch64/AArch64InstrInfo.td =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.td +++ lib/Target/AArch64/AArch64InstrInfo.td @@ -5233,6 +5233,9 @@ def : Pat<(f128 (bitconvert (v8i16 FPR128:$src))), (f128 (EXTv16i8 (REV64v8i16 FPR128:$src), (REV64v8i16 FPR128:$src), (i32 8)))>; +def : Pat<(f128 (bitconvert (v8f16 FPR128:$src))), + (f128 (EXTv16i8 (REV64v8i16 FPR128:$src), + (REV64v8i16 FPR128:$src), (i32 8)))>; def : Pat<(f128 (bitconvert (v2f64 FPR128:$src))), (f128 (EXTv16i8 FPR128:$src, FPR128:$src, (i32 8)))>; def : Pat<(f128 (bitconvert (v4f32 FPR128:$src))), @@ -5247,6 +5250,7 @@ def : Pat<(v2f64 (bitconvert (f128 FPR128:$src))), (v2f64 FPR128:$src)>; def : Pat<(v2f64 (bitconvert (v4i32 FPR128:$src))), (v2f64 FPR128:$src)>; def : Pat<(v2f64 (bitconvert (v8i16 FPR128:$src))), (v2f64 FPR128:$src)>; +def : Pat<(v2f64 (bitconvert (v8f16 FPR128:$src))), (v2f64 FPR128:$src)>; def : Pat<(v2f64 (bitconvert (v16i8 FPR128:$src))), (v2f64 FPR128:$src)>; def : Pat<(v2f64 (bitconvert (v4f32 FPR128:$src))), (v2f64 FPR128:$src)>; } @@ -5258,6 +5262,8 @@ (v2f64 (REV64v4i32 FPR128:$src))>; def : Pat<(v2f64 (bitconvert (v8i16 FPR128:$src))), (v2f64 (REV64v8i16 FPR128:$src))>; +def : Pat<(v2f64 (bitconvert (v8f16 FPR128:$src))), + (v2f64 (REV64v8i16 FPR128:$src))>; def : Pat<(v2f64 (bitconvert (v16i8 FPR128:$src))), (v2f64 (REV64v16i8 FPR128:$src))>; def : Pat<(v2f64 (bitconvert (v4f32 FPR128:$src))), @@ -5268,6 +5274,7 @@ let Predicates = [IsLE] in { def : Pat<(v4f32 (bitconvert (f128 FPR128:$src))), (v4f32 FPR128:$src)>; def : Pat<(v4f32 (bitconvert (v8i16 FPR128:$src))), (v4f32 FPR128:$src)>; +def : Pat<(v4f32 (bitconvert (v8f16 FPR128:$src))), (v4f32 FPR128:$src)>; def : Pat<(v4f32 (bitconvert (v16i8 FPR128:$src))), (v4f32 FPR128:$src)>; def : Pat<(v4f32 (bitconvert (v2i64 FPR128:$src))), (v4f32 FPR128:$src)>; def : Pat<(v4f32 (bitconvert (v2f64 FPR128:$src))), (v4f32 FPR128:$src)>; @@ -5278,6 +5285,8 @@ (REV64v4i32 FPR128:$src), (i32 8)))>; def : Pat<(v4f32 (bitconvert (v8i16 FPR128:$src))), (v4f32 (REV32v8i16 FPR128:$src))>; +def : Pat<(v4f32 (bitconvert (v8f16 FPR128:$src))), + (v4f32 (REV32v8i16 FPR128:$src))>; def : Pat<(v4f32 (bitconvert (v16i8 FPR128:$src))), (v4f32 (REV32v16i8 FPR128:$src))>; def : Pat<(v4f32 (bitconvert (v2i64 FPR128:$src))), Index: test/CodeGen/AArch64/aarch64_f16_be.ll =================================================================== --- /dev/null +++ test/CodeGen/AArch64/aarch64_f16_be.ll @@ -0,0 +1,41 @@ +; RUN: llc -mtriple=aarch64-linux-gnuabi -O0 < %s | FileCheck %s +; RUN: llc -mtriple=aarch64_be-linux-gnuabi -O0 < %s | FileCheck %s --check-prefix=CHECK-BE + +define void @test_bitcast_v8f16_to_v4f32(<8 x half> %a) { +; CHECK-LABEL: test_bitcast_v8f16_to_v4f32: +; CHECK-NOT: st1 + +; CHECK-BE-LABEL: test_bitcast_v8f16_to_v4f32: +; CHECK-BE: st1 + + %x = alloca <4 x float>, align 16 + %y = bitcast <8 x half> %a to <4 x float> + store <4 x float> %y, <4 x float>* %x, align 16 + ret void +} + +define void @test_bitcast_v8f16_to_v2f64(<8 x half> %a) { +; CHECK-LABEL: test_bitcast_v8f16_to_v2f64: +; CHECK-NOT: st1 + +; CHECK-BE-LABEL: test_bitcast_v8f16_to_v2f64: +; CHECK-BE: st1 + + %x = alloca <2 x double>, align 16 + %y = bitcast <8 x half> %a to <2 x double> + store <2 x double> %y, <2 x double>* %x, align 16 + ret void +} + +define void @test_bitcast_v8f16_to_fp128(<8 x half> %a) { +; CHECK-LABEL: test_bitcast_v8f16_to_fp128: +; CHECK-NOT: st1 + +; CHECK-BE-LABEL: test_bitcast_v8f16_to_fp128: +; CHECK-BE: st1 + + %x = alloca fp128, align 16 + %y = bitcast <8 x half> %a to fp128 + store fp128 %y, fp128* %x, align 16 + ret void +}