[AArch64] Implement the isZExtFree APIs.
authorChad Rosier <mcrosier@codeaurora.org>
Wed, 9 Apr 2014 20:51:21 +0000 (20:51 +0000)
committerChad Rosier <mcrosier@codeaurora.org>
Wed, 9 Apr 2014 20:51:21 +0000 (20:51 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205926 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/AArch64ISelLowering.cpp
lib/Target/AArch64/AArch64ISelLowering.h
test/CodeGen/AArch64/free-zext.ll [new file with mode: 0644]
test/CodeGen/AArch64/regress-tblgen-chains.ll

index 7accadc6a0f843308ab6233e49d620bca4fb84ad..589734d80fee828dd12c64026ab3e5d0804080a0 100644 (file)
@@ -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);
+}
index 6a4b0c791fea82b64f8c3b0cd8f8dea726ef6c82..5932e1d1fe53853e92674e6c8ef746764f10d5da 100644 (file)
@@ -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 (file)
index 0000000..7fae016
--- /dev/null
@@ -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
+}
index ff77fb4e48f7efa32f7e4c04f6d9df9ecaf77fad..a013a450e92e864f30adfc02741f55e225f20cc2 100644 (file)
@@ -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]]]