From 8b62d78689bfdfa72f7ded3ad0bd0de412a55831 Mon Sep 17 00:00:00 2001 From: Juergen Ributzka Date: Tue, 18 Nov 2014 19:58:59 +0000 Subject: [PATCH] [FastISel][AArch64] Fix shift-immediate emission for "zero" shifts. This change emits a COPY for a shift-immediate with a "zero" shift value. This fixes PR21594 where we emitted a shift instruction with an incorrect immediate operand. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222247 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64FastISel.cpp | 39 +++++++++++++++++++++---- test/CodeGen/AArch64/fast-isel-shift.ll | 25 +++++++++++++++- 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/lib/Target/AArch64/AArch64FastISel.cpp b/lib/Target/AArch64/AArch64FastISel.cpp index 4d18a4e0b0f..eaa89b22628 100644 --- a/lib/Target/AArch64/AArch64FastISel.cpp +++ b/lib/Target/AArch64/AArch64FastISel.cpp @@ -3899,6 +3899,17 @@ unsigned AArch64FastISel::emitLSL_ri(MVT RetVT, MVT SrcVT, unsigned Op0, unsigned RegSize = Is64Bit ? 64 : 32; unsigned DstBits = RetVT.getSizeInBits(); unsigned SrcBits = SrcVT.getSizeInBits(); + const TargetRegisterClass *RC = + Is64Bit ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass; + + // Just emit a copy for "zero" shifts. + if (Shift == 0) { + unsigned ResultReg = createResultReg(RC); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, + TII.get(TargetOpcode::COPY), ResultReg) + .addReg(Op0, getKillRegState(Op0IsKill)); + return ResultReg; + } // Don't deal with undefined shifts. if (Shift >= DstBits) @@ -3937,8 +3948,6 @@ unsigned AArch64FastISel::emitLSL_ri(MVT RetVT, MVT SrcVT, unsigned Op0, {AArch64::UBFMWri, AArch64::UBFMXri} }; unsigned Opc = OpcTable[IsZext][Is64Bit]; - const TargetRegisterClass *RC = - Is64Bit ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass; if (SrcVT.SimpleTy <= MVT::i32 && RetVT == MVT::i64) { unsigned TmpReg = MRI.createVirtualRegister(RC); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, @@ -3993,6 +4002,17 @@ unsigned AArch64FastISel::emitLSR_ri(MVT RetVT, MVT SrcVT, unsigned Op0, unsigned RegSize = Is64Bit ? 64 : 32; unsigned DstBits = RetVT.getSizeInBits(); unsigned SrcBits = SrcVT.getSizeInBits(); + const TargetRegisterClass *RC = + Is64Bit ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass; + + // Just emit a copy for "zero" shifts. + if (Shift == 0) { + unsigned ResultReg = createResultReg(RC); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, + TII.get(TargetOpcode::COPY), ResultReg) + .addReg(Op0, getKillRegState(Op0IsKill)); + return ResultReg; + } // Don't deal with undefined shifts. if (Shift >= DstBits) @@ -4045,8 +4065,6 @@ unsigned AArch64FastISel::emitLSR_ri(MVT RetVT, MVT SrcVT, unsigned Op0, {AArch64::UBFMWri, AArch64::UBFMXri} }; unsigned Opc = OpcTable[IsZExt][Is64Bit]; - const TargetRegisterClass *RC = - Is64Bit ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass; if (SrcVT.SimpleTy <= MVT::i32 && RetVT == MVT::i64) { unsigned TmpReg = MRI.createVirtualRegister(RC); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, @@ -4101,6 +4119,17 @@ unsigned AArch64FastISel::emitASR_ri(MVT RetVT, MVT SrcVT, unsigned Op0, unsigned RegSize = Is64Bit ? 64 : 32; unsigned DstBits = RetVT.getSizeInBits(); unsigned SrcBits = SrcVT.getSizeInBits(); + const TargetRegisterClass *RC = + Is64Bit ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass; + + // Just emit a copy for "zero" shifts. + if (Shift == 0) { + unsigned ResultReg = createResultReg(RC); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, + TII.get(TargetOpcode::COPY), ResultReg) + .addReg(Op0, getKillRegState(Op0IsKill)); + return ResultReg; + } // Don't deal with undefined shifts. if (Shift >= DstBits) @@ -4141,8 +4170,6 @@ unsigned AArch64FastISel::emitASR_ri(MVT RetVT, MVT SrcVT, unsigned Op0, {AArch64::UBFMWri, AArch64::UBFMXri} }; unsigned Opc = OpcTable[IsZExt][Is64Bit]; - const TargetRegisterClass *RC = - Is64Bit ? &AArch64::GPR64RegClass : &AArch64::GPR32RegClass; if (SrcVT.SimpleTy <= MVT::i32 && RetVT == MVT::i64) { unsigned TmpReg = MRI.createVirtualRegister(RC); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, diff --git a/test/CodeGen/AArch64/fast-isel-shift.ll b/test/CodeGen/AArch64/fast-isel-shift.ll index e4a3b860d2e..fd3ee27a4b6 100644 --- a/test/CodeGen/AArch64/fast-isel-shift.ll +++ b/test/CodeGen/AArch64/fast-isel-shift.ll @@ -1,4 +1,4 @@ -; RUN: llc -fast-isel -fast-isel-abort -mtriple=arm64-apple-darwin -verify-machineinstrs < %s | FileCheck %s +; RUN: llc -fast-isel -fast-isel-abort -mtriple=aarch64-apple-darwin -verify-machineinstrs < %s | FileCheck %s ; CHECK-LABEL: lsl_zext_i1_i16 ; CHECK: ubfiz {{w[0-9]*}}, {{w[0-9]*}}, #4, #1 @@ -404,3 +404,26 @@ define i32 @shift_test1(i8 %a) { ret i32 %3 } +; Test zero shifts + +; CHECK-LABEL: shl_zero +; CHECK-NOT: lsl +define i32 @shl_zero(i32 %a) { + %1 = shl i32 %a, 0 + ret i32 %1 +} + +; CHECK-LABEL: lshr_zero +; CHECK-NOT: lsr +define i32 @lshr_zero(i32 %a) { + %1 = lshr i32 %a, 0 + ret i32 %1 +} + +; CHECK-LABEL: ashr_zero +; CHECK-NOT: asr +define i32 @ashr_zero(i32 %a) { + %1 = ashr i32 %a, 0 + ret i32 %1 +} +