From: Juergen Ributzka Date: Wed, 13 Aug 2014 22:13:14 +0000 (+0000) Subject: [FastISel][AArch64] Make use of the zero register when possible. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=dc408e806928e534d2925b06f638c4e381403f56;p=llvm [FastISel][AArch64] Make use of the zero register when possible. 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@215591 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/AArch64/AArch64FastISel.cpp b/lib/Target/AArch64/AArch64FastISel.cpp index 918e0cec0f9..316111d432d 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