From c3de5ed0728c1834b14e4cea82a53e40ed8e4e23 Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Wed, 9 Apr 2014 20:51:21 +0000 Subject: [PATCH] [AArch64] Implement the isZExtFree APIs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205926 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64ISelLowering.cpp | 36 +++++++++++++++++++ lib/Target/AArch64/AArch64ISelLowering.h | 4 +++ test/CodeGen/AArch64/free-zext.ll | 14 ++++++++ test/CodeGen/AArch64/regress-tblgen-chains.ll | 2 +- 4 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 test/CodeGen/AArch64/free-zext.ll diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp index 7accadc6a0f..589734d80fe 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -5389,3 +5389,39 @@ bool AArch64TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const { return false; return true; } + +// All 32-bit GPR operations implicitly zero the high-half of the corresponding +// 64-bit GPR. +bool AArch64TargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const { + if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy()) + return false; + unsigned NumBits1 = Ty1->getPrimitiveSizeInBits(); + unsigned NumBits2 = Ty2->getPrimitiveSizeInBits(); + if (NumBits1 == 32 && NumBits2 == 64) + return true; + return false; +} + +bool AArch64TargetLowering::isZExtFree(EVT VT1, EVT VT2) const { + if (!VT1.isInteger() || !VT2.isInteger()) + return false; + unsigned NumBits1 = VT1.getSizeInBits(); + unsigned NumBits2 = VT2.getSizeInBits(); + if (NumBits1 == 32 && NumBits2 == 64) + return true; + return false; +} + +bool AArch64TargetLowering::isZExtFree(SDValue Val, EVT VT2) const { + EVT VT1 = Val.getValueType(); + if (isZExtFree(VT1, VT2)) { + return true; + } + + if (Val.getOpcode() != ISD::LOAD) + return false; + + // 8-, 16-, and 32-bit integer loads all implicitly zero-extend. + return (VT1.isSimple() && VT1.isInteger() && VT2.isSimple() && + VT2.isInteger() && VT1.getSizeInBits() <= 32); +} diff --git a/lib/Target/AArch64/AArch64ISelLowering.h b/lib/Target/AArch64/AArch64ISelLowering.h index 6a4b0c791fe..5932e1d1fe5 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.h +++ b/lib/Target/AArch64/AArch64ISelLowering.h @@ -281,6 +281,10 @@ public: bool isTruncateFree(Type *Ty1, Type *Ty2) const override; bool isTruncateFree(EVT VT1, EVT VT2) const override; + bool isZExtFree(Type *Ty1, Type *Ty2) const override; + bool isZExtFree(EVT VT1, EVT VT2) const override; + bool isZExtFree(SDValue Val, EVT VT2) const override; + SDValue getSelectableIntSetCC(SDValue LHS, SDValue RHS, ISD::CondCode CC, SDValue &A64cc, SelectionDAG &DAG, SDLoc &dl) const; diff --git a/test/CodeGen/AArch64/free-zext.ll b/test/CodeGen/AArch64/free-zext.ll new file mode 100644 index 00000000000..7fae01653b3 --- /dev/null +++ b/test/CodeGen/AArch64/free-zext.ll @@ -0,0 +1,14 @@ +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +define i64 @test_free_zext(i8* %a, i16* %b) { +; CHECK-LABEL: test_free_zext +; CHECK: ldrb w0, [x0] +; CHECK: ldrh w1, [x1] +; CHECK: add x0, x1, x0 + %1 = load i8* %a, align 1 + %conv = zext i8 %1 to i64 + %2 = load i16* %b, align 2 + %conv1 = zext i16 %2 to i64 + %add = add nsw i64 %conv1, %conv + ret i64 %add +} diff --git a/test/CodeGen/AArch64/regress-tblgen-chains.ll b/test/CodeGen/AArch64/regress-tblgen-chains.ll index ff77fb4e48f..a013a450e92 100644 --- a/test/CodeGen/AArch64/regress-tblgen-chains.ll +++ b/test/CodeGen/AArch64/regress-tblgen-chains.ll @@ -25,7 +25,7 @@ define i64 @test_chains() { %inc.4 = trunc i64 %inc.3 to i8 store i8 %inc.4, i8* %locvar ; CHECK: ldrb {{w[0-9]+}}, [sp, [[LOCADDR:#[0-9]+]]] -; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, #1 +; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, #1 ; CHECK: strb {{w[0-9]+}}, [sp, [[LOCADDR]]] ; CHECK: ldrb {{w[0-9]+}}, [sp, [[LOCADDR]]]