From b6fdce4ca0f35aabab76ed428552a7ee68518863 Mon Sep 17 00:00:00 2001 From: Nemanja Ivanovic Date: Thu, 4 Feb 2016 23:14:42 +0000 Subject: [PATCH] Fix for PR 26356 Using the load immediate only when the immediate (whether signed or unsigned) can fit in a 16-bit signed field. Namely, from -32768 to 32767 for signed and 0 to 65535 for unsigned. This patch also ensures that we sign-extend under the right conditions. llvm-svn: 259840 --- llvm/lib/Target/PowerPC/PPCFastISel.cpp | 9 +-- llvm/test/CodeGen/PowerPC/pr26356.ll | 136 ++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+), 5 deletions(-) create mode 100644 llvm/test/CodeGen/PowerPC/pr26356.ll diff --git a/llvm/lib/Target/PowerPC/PPCFastISel.cpp b/llvm/lib/Target/PowerPC/PPCFastISel.cpp index 795fd6d..3980ecf 100644 --- a/llvm/lib/Target/PowerPC/PPCFastISel.cpp +++ b/llvm/lib/Target/PowerPC/PPCFastISel.cpp @@ -1615,7 +1615,7 @@ bool PPCFastISel::SelectRet(const Instruction *I) { // extension rather than sign extension. Make sure we pass the return // value extension property to integer materialization. unsigned SrcReg = - PPCMaterializeInt(CI, MVT::i64, VA.getLocInfo() == CCValAssign::SExt); + PPCMaterializeInt(CI, MVT::i64, VA.getLocInfo() != CCValAssign::ZExt); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(TargetOpcode::COPY), RetReg).addReg(SrcReg); @@ -2090,22 +2090,21 @@ unsigned PPCFastISel::PPCMaterializeInt(const ConstantInt *CI, MVT VT, const TargetRegisterClass *RC = ((VT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass); + int64_t Imm = UseSExt ? CI->getSExtValue() : CI->getZExtValue(); // If the constant is in range, use a load-immediate. // Since LI will sign extend the constant we need to make sure that for // our zeroext constants that the sign extended constant fits into 16-bits - // a range of 0..0x7fff. - if ((UseSExt && isInt<16>(CI->getSExtValue())) || - (!UseSExt && isUInt<16>(CI->getSExtValue()))) { + if (isInt<16>(Imm)) { unsigned Opc = (VT == MVT::i64) ? PPC::LI8 : PPC::LI; unsigned ImmReg = createResultReg(RC); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ImmReg) - .addImm(CI->getSExtValue()); + .addImm(Imm); return ImmReg; } // Construct the constant piecewise. - int64_t Imm = UseSExt ? CI->getSExtValue() : CI->getZExtValue(); if (VT == MVT::i64) return PPCMaterialize64BitInt(Imm, RC); else if (VT == MVT::i32) diff --git a/llvm/test/CodeGen/PowerPC/pr26356.ll b/llvm/test/CodeGen/PowerPC/pr26356.ll new file mode 100644 index 0000000..0f5d877 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/pr26356.ll @@ -0,0 +1,136 @@ +; RUN: llc -O0 -mcpu=pwr7 -mtriple=powerpc64le-unknown-unknown < %s | FileCheck %s + +define zeroext i32 @f1() { +entry: + ret i32 65535 +} +; CHECK-LABEL: @f1 +; CHECK: lis 3, 0 +; CHECK: ori 3, 3, 65535 + +define zeroext i32 @f2() { +entry: + ret i32 32768 +} +; CHECK-LABEL: @f2 +; CHECK: lis 3, 0 +; CHECK: ori 3, 3, 32768 + +define zeroext i32 @f3() { +entry: + ret i32 32767 +} +; CHECK-LABEL: @f3 +; CHECK: li 3, 32767 + +define zeroext i16 @f4() { +entry: + ret i16 65535 +} +; CHECK-LABEL: @f4 +; CHECK: lis 3, 0 +; CHECK: ori 3, 3, 65535 + +define zeroext i16 @f5() { +entry: + ret i16 32768 +} +; CHECK-LABEL: @f5 +; CHECK: lis 3, 0 +; CHECK: ori 3, 3, 32768 + +define zeroext i16 @f6() { +entry: + ret i16 32767 +} +; CHECK-LABEL: @f6 +; CHECK: li 3, 32767 + +define zeroext i16 @f7() { +entry: + ret i16 -1 +} +; CHECK-LABEL: @f7 +; CHECK: lis 3, 0 +; CHECK: ori 3, 3, 65535 + +define zeroext i16 @f8() { +entry: + ret i16 -32768 +} +; CHECK-LABEL: @f8 +; CHECK: lis 3, 0 +; CHECK: ori 3, 3, 32768 + +define signext i32 @f1s() { +entry: + ret i32 65535 +} +; CHECK-LABEL: @f1s +; CHECK: lis 3, 0 +; CHECK: ori 3, 3, 65535 + +define signext i32 @f2s() { +entry: + ret i32 32768 +} +; CHECK-LABEL: @f2s +; CHECK: lis 3, 0 +; CHECK: ori 3, 3, 32768 + +define signext i32 @f3s() { +entry: + ret i32 32767 +} +; CHECK-LABEL: @f3s +; CHECK: li 3, 32767 + +define signext i16 @f4s() { +entry: + ret i16 32767 +} +; CHECK-LABEL: @f4s +; CHECK: li 3, 32767 + +define signext i32 @f1sn() { +entry: + ret i32 -65535 +} +; CHECK-LABEL: @f1sn +; CHECK: lis 3, -1 +; CHECK: ori 3, 3, 1 + +define signext i32 @f2sn() { +entry: + ret i32 -32768 +} +; CHECK-LABEL: @f2sn +; CHECK: li 3, -32768 + +define signext i32 @f3sn() { +entry: + ret i32 -32767 +} +; CHECK-LABEL: @f3sn +; CHECK: li 3, -32767 + +define signext i32 @f4sn() { +entry: + ret i32 -65536 +} +; CHECK-LABEL: @f4sn +; CHECK: lis 3, -1 + +define signext i16 @f5sn() { +entry: + ret i16 -32767 +} +; CHECK-LABEL: @f5sn +; CHECK: li 3, -32767 + +define signext i16 @f6sn() { +entry: + ret i16 -32768 +} +; CHECK-LABEL: @f6sn +; CHECK: li 3, -32768 -- 2.7.4