From e7f8191b1863defb50c28a2b41a9d368d9ad6384 Mon Sep 17 00:00:00 2001 From: Louis Gerbarg Date: Mon, 7 Jul 2014 21:37:51 +0000 Subject: [PATCH] Allow AArch64FastISel to degrade graceully in the presence of an MVT::i128 Currently AArch64FastISel crashes if it tries to extend an integer into an MVT::i128. This can happen by creating 128 bit integers like so: typedef unsigned int uint128_t __attribute__((mode(TI))); typedef int sint128_t __attribute__((mode(TI))); This patch makes EmitIntExt check for their presence and then falls back to SelectionDAG. Tests included. rdar://17516686 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212492 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64FastISel.cpp | 6 ++++++ .../CodeGen/AArch64/i128-fast-isel-fallback.ll | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 test/CodeGen/AArch64/i128-fast-isel-fallback.ll diff --git a/lib/Target/AArch64/AArch64FastISel.cpp b/lib/Target/AArch64/AArch64FastISel.cpp index cc2a70ee8a2..d822c1bf327 100644 --- a/lib/Target/AArch64/AArch64FastISel.cpp +++ b/lib/Target/AArch64/AArch64FastISel.cpp @@ -1750,6 +1750,12 @@ unsigned AArch64FastISel::Emiti1Ext(unsigned SrcReg, MVT DestVT, bool isZExt) { unsigned AArch64FastISel::EmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, bool isZExt) { assert(DestVT != MVT::i1 && "ZeroExt/SignExt an i1?"); + + // FastISel does not have plumbing to deal with an MVT::i128, if we see one + // so rather than return one we need to bail out to SelectionDAG. + if (DestVT == MVT::i128) + return 0; + unsigned Opc; unsigned Imm = 0; diff --git a/test/CodeGen/AArch64/i128-fast-isel-fallback.ll b/test/CodeGen/AArch64/i128-fast-isel-fallback.ll new file mode 100644 index 00000000000..1cffbf3de05 --- /dev/null +++ b/test/CodeGen/AArch64/i128-fast-isel-fallback.ll @@ -0,0 +1,18 @@ +; RUN: llc -O0 -mtriple=arm64-apple-ios7.0 -mcpu=generic < %s | FileCheck %s + +; Function Attrs: nounwind ssp +define void @test1() { + %1 = sext i32 0 to i128 + call void @test2(i128 %1) + ret void + +; The i128 is 0 so the we can test to make sure it is propogated into the x +; registers that make up the i128 pair + +; CHECK: mov x0, xzr +; CHECK: mov x1, x0 +; CHECK: bl _test2 + +} + +declare void @test2(i128)