From 217a4a87ce1ffef091248665735980839a306dbb Mon Sep 17 00:00:00 2001 From: Ahmed Bougacha Date: Mon, 1 Dec 2014 20:52:32 +0000 Subject: [PATCH] [AArch64] Fix v2i8->i16 bitcast legalization. r213378 improved f16 bitcasts, so that they go directly through subregs, instead of through the stack. That code now causes an assertion failure for bitcasts from other 16-bits types (most importantly v2i8). Correct that by doing the custom lowering for i16 bitcasts only when the input is an f16. Part of PR21549. Differential Revision: http://reviews.llvm.org/D6307 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223074 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64ISelLowering.cpp | 9 ++++----- test/CodeGen/AArch64/bitcast-v2i8.ll | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 test/CodeGen/AArch64/bitcast-v2i8.ll diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp index 6da468ed6b1..16ad2f6e3b5 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -8697,13 +8697,12 @@ bool AArch64TargetLowering::getPostIndexedAddressParts( static void ReplaceBITCASTResults(SDNode *N, SmallVectorImpl &Results, SelectionDAG &DAG) { - if (N->getValueType(0) != MVT::i16) - return; - SDLoc DL(N); SDValue Op = N->getOperand(0); - assert(Op.getValueType() == MVT::f16 && - "Inconsistent bitcast? Only 16-bit types should be i16 or f16"); + + if (N->getValueType(0) != MVT::i16 || Op.getValueType() != MVT::f16) + return; + Op = SDValue( DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, DL, MVT::f32, DAG.getUNDEF(MVT::i32), Op, diff --git a/test/CodeGen/AArch64/bitcast-v2i8.ll b/test/CodeGen/AArch64/bitcast-v2i8.ll new file mode 100644 index 00000000000..4bdac641c5b --- /dev/null +++ b/test/CodeGen/AArch64/bitcast-v2i8.ll @@ -0,0 +1,15 @@ +; RUN: llc < %s -mtriple=aarch64-apple-ios | FileCheck %s + +; Part of PR21549: going through the stack isn't ideal but is correct. + +define i16 @test_bitcast_v2i8_to_i16(<2 x i8> %a) { +; CHECK-LABEL: test_bitcast_v2i8_to_i16 +; CHECK: mov.s [[WREG_HI:w[0-9]+]], v0[1] +; CHECK-NEXT: fmov [[WREG_LO:w[0-9]+]], s0 +; CHECK-NEXT: strb [[WREG_HI]], [sp, #15] +; CHECK-NEXT: strb [[WREG_LO]], [sp, #14] +; CHECK-NEXT: ldrh w0, [sp, #14] + + %aa = bitcast <2 x i8> %a to i16 + ret i16 %aa +} -- 2.34.1