From 78f686d37cc3b4e70bbfc2acdfcfec8443fd3250 Mon Sep 17 00:00:00 2001 From: Juergen Ributzka Date: Tue, 19 Aug 2014 19:44:02 +0000 Subject: [PATCH] Reapply [FastISel][AArch64] Make use of the zero register when possible (r215591). Note: This was originally reverted to track down a buildbot error. Reapply without any modifications. Original commit message: This change materializes now the value "0" from the zero register. The zero register can be folded by several instruction, so no materialization is need at all. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216009 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64FastISel.cpp | 14 ++++++++- test/CodeGen/AArch64/arm64-fast-isel-call.ll | 25 ++++++++-------- .../AArch64/arm64-fast-isel-intrinsic.ll | 2 +- test/CodeGen/AArch64/arm64-fast-isel-store.ll | 30 +++++++++++++++++++ test/CodeGen/AArch64/arm64-fast-isel.ll | 4 +-- 5 files changed, 59 insertions(+), 16 deletions(-) create mode 100644 test/CodeGen/AArch64/arm64-fast-isel-store.ll diff --git a/lib/Target/AArch64/AArch64FastISel.cpp b/lib/Target/AArch64/AArch64FastISel.cpp index 78b46b8f8d3..41588d78bb6 100644 --- a/lib/Target/AArch64/AArch64FastISel.cpp +++ b/lib/Target/AArch64/AArch64FastISel.cpp @@ -217,7 +217,19 @@ unsigned AArch64FastISel::TargetMaterializeAlloca(const AllocaInst *AI) { unsigned AArch64FastISel::AArch64MaterializeInt(const ConstantInt *CI, MVT VT) { if (VT > MVT::i64) return 0; - return FastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue()); + + if (!CI->isZero()) + return FastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue()); + + // Create a copy from the zero register to materialize a "0" value. + const TargetRegisterClass *RC = (VT == MVT::i64) ? &AArch64::GPR64RegClass + : &AArch64::GPR32RegClass; + unsigned ZeroReg = (VT == MVT::i64) ? AArch64::XZR : AArch64::WZR; + unsigned ResultReg = createResultReg(RC); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, + TII.get(TargetOpcode::COPY), ResultReg) + .addReg(ZeroReg, getKillRegState(true)); + return ResultReg; } unsigned AArch64FastISel::AArch64MaterializeFP(const ConstantFP *CFP, MVT VT) { diff --git a/test/CodeGen/AArch64/arm64-fast-isel-call.ll b/test/CodeGen/AArch64/arm64-fast-isel-call.ll index 302485837d4..34a227a9dc0 100644 --- a/test/CodeGen/AArch64/arm64-fast-isel-call.ll +++ b/test/CodeGen/AArch64/arm64-fast-isel-call.ll @@ -42,7 +42,7 @@ entry: define i32 @sext_(i8 %a, i16 %b) nounwind { entry: -; CHECK-LABEL: @sext_ +; CHECK-LABEL: sext_ ; CHECK: sxtb w0, w0 ; CHECK: sxth w1, w1 ; CHECK: bl _foo_sext_ @@ -54,7 +54,7 @@ declare void @foo_sext_(i8 %a, i16 %b) define i32 @zext_(i8 %a, i16 %b) nounwind { entry: -; CHECK-LABEL: @zext_ +; CHECK-LABEL: zext_ ; CHECK: uxtb w0, w0 ; CHECK: uxth w1, w1 call void @foo_zext_(i8 zeroext %a, i16 zeroext %b) @@ -78,17 +78,18 @@ declare i32 @bar(i8 zeroext, i8 zeroext, i8 zeroext, i8 zeroext, i8 zeroext, i8 ; Test materialization of integers. Target-independent selector handles this. define i32 @t2() { entry: -; CHECK-LABEL: @t2 -; CHECK: movz x0, #0 +; CHECK-LABEL: t2 +; CHECK: mov [[REG1:x[0-9]+]], xzr ; CHECK: orr w1, wzr, #0xfffffff8 -; CHECK: orr w[[REG:[0-9]+]], wzr, #0x3ff -; CHECK: orr w[[REG2:[0-9]+]], wzr, #0x2 -; CHECK: movz w[[REG3:[0-9]+]], #0 -; CHECK: orr w[[REG4:[0-9]+]], wzr, #0x1 -; CHECK: uxth w2, w[[REG]] -; CHECK: sxtb w3, w[[REG2]] -; CHECK: and w4, w[[REG3]], #0x1 -; CHECK: and w5, w[[REG4]], #0x1 +; CHECK: orr [[REG2:w[0-9]+]], wzr, #0x3ff +; CHECK: orr [[REG3:w[0-9]+]], wzr, #0x2 +; CHECK: mov [[REG4:w[0-9]+]], wzr +; CHECK: orr [[REG5:w[0-9]+]], wzr, #0x1 +; CHECK: mov x0, [[REG1]] +; CHECK: uxth w2, [[REG2]] +; CHECK: sxtb w3, [[REG3]] +; CHECK: and w4, [[REG4]], #0x1 +; CHECK: and w5, [[REG5]], #0x1 ; CHECK: bl _func2 %call = call i32 @func2(i64 zeroext 0, i32 signext -8, i16 zeroext 1023, i8 signext -254, i1 zeroext 0, i1 zeroext 1) ret i32 0 diff --git a/test/CodeGen/AArch64/arm64-fast-isel-intrinsic.ll b/test/CodeGen/AArch64/arm64-fast-isel-intrinsic.ll index 115298805ac..b16c899f421 100644 --- a/test/CodeGen/AArch64/arm64-fast-isel-intrinsic.ll +++ b/test/CodeGen/AArch64/arm64-fast-isel-intrinsic.ll @@ -7,7 +7,7 @@ define void @t1() { ; ARM64-LABEL: t1 ; ARM64: adrp x8, _message@PAGE ; ARM64: add x0, x8, _message@PAGEOFF -; ARM64: movz w9, #0 +; ARM64: mov w9, wzr ; ARM64: movz x2, #0x50 ; ARM64: uxtb w1, w9 ; ARM64: bl _memset diff --git a/test/CodeGen/AArch64/arm64-fast-isel-store.ll b/test/CodeGen/AArch64/arm64-fast-isel-store.ll new file mode 100644 index 00000000000..362224fd0ca --- /dev/null +++ b/test/CodeGen/AArch64/arm64-fast-isel-store.ll @@ -0,0 +1,30 @@ +; RUN: llc -mtriple=aarch64-unknown-unknown < %s | FileCheck %s +; RUN: llc -mtriple=aarch64-unknown-unknown -fast-isel -fast-isel-abort < %s | FileCheck %s + +define void @store_i8(i8* %a) { +; CHECK-LABEL: store_i8 +; CHECK: strb wzr, [x0] + store i8 0, i8* %a + ret void +} + +define void @store_i16(i16* %a) { +; CHECK-LABEL: store_i16 +; CHECK: strh wzr, [x0] + store i16 0, i16* %a + ret void +} + +define void @store_i32(i32* %a) { +; CHECK-LABEL: store_i32 +; CHECK: str wzr, [x0] + store i32 0, i32* %a + ret void +} + +define void @store_i64(i64* %a) { +; CHECK-LABEL: store_i64 +; CHECK: str xzr, [x0] + store i64 0, i64* %a + ret void +} diff --git a/test/CodeGen/AArch64/arm64-fast-isel.ll b/test/CodeGen/AArch64/arm64-fast-isel.ll index 0194b3a6c2d..a71bdb2a3df 100644 --- a/test/CodeGen/AArch64/arm64-fast-isel.ll +++ b/test/CodeGen/AArch64/arm64-fast-isel.ll @@ -66,7 +66,7 @@ entry: define void @t4(i32 *%ptr) nounwind { entry: ; CHECK-LABEL: t4: -; CHECK: movz w8, #0 +; CHECK: mov w8, wzr ; CHECK: stur w8, [x0, #-4] ; CHECK: ret %0 = getelementptr i32 *%ptr, i32 -1 @@ -77,7 +77,7 @@ entry: define void @t5(i32 *%ptr) nounwind { entry: ; CHECK-LABEL: t5: -; CHECK: movz w8, #0 +; CHECK: mov w8, wzr ; CHECK: stur w8, [x0, #-256] ; CHECK: ret %0 = getelementptr i32 *%ptr, i32 -64 -- 2.34.1