From e05397b4aea8e63cdc3f9a663ebcec39d21333b9 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Sat, 25 Jul 2015 00:48:08 +0000 Subject: [PATCH] Fix PPCMaterializeInt to check the size of the integer based on the extension property we're requesting - zero or sign extended. This fixes cases where we want to return a zero extended 32-bit -1 and not be sign extended for the entire register. Also updated the already out of date comment with the current behavior. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243192 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/PPCFastISel.cpp | 23 ++++++++++++++--------- test/CodeGen/PowerPC/fast-isel-ret.ll | 10 ++++++++++ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/lib/Target/PowerPC/PPCFastISel.cpp b/lib/Target/PowerPC/PPCFastISel.cpp index 7c184f4bdd0..700df20f8aa 100644 --- a/lib/Target/PowerPC/PPCFastISel.cpp +++ b/lib/Target/PowerPC/PPCFastISel.cpp @@ -1608,17 +1608,16 @@ bool PPCFastISel::SelectRet(const Instruction *I) { if (ValLocs.size() > 1) return false; - // Special case for returning a constant integer of any size. - // Materialize the constant as an i64 and copy it to the return - // register. We still need to worry about properly extending the sign. E.g: - // If the constant has only one bit, it means it is a boolean. Therefore - // we can't use PPCMaterializeInt because it extends the sign which will - // cause negations of the returned value to be incorrect as they are - // implemented as the flip of the least significant bit. + // Special case for returning a constant integer of any size - materialize + // the constant as an i64 and copy it to the return register. if (const ConstantInt *CI = dyn_cast(RV)) { CCValAssign &VA = ValLocs[0]; unsigned RetReg = VA.getLocReg(); + // We still need to worry about properly extending the sign. For example, + // we could have only a single bit or a constant that needs zero + // 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); @@ -2103,11 +2102,17 @@ unsigned PPCFastISel::PPCMaterializeInt(const ConstantInt *CI, MVT VT, &PPC::GPRCRegClass); // If the constant is in range, use a load-immediate. - if (isInt<16>(CI->getSExtValue())) { + if (UseSExt && isInt<16>(CI->getSExtValue())) { unsigned Opc = (VT == MVT::i64) ? PPC::LI8 : PPC::LI; unsigned ImmReg = createResultReg(RC); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ImmReg) - .addImm( (UseSExt) ? CI->getSExtValue() : CI->getZExtValue() ); + .addImm(CI->getSExtValue()); + return ImmReg; + } else if (!UseSExt && isUInt<16>(CI->getZExtValue())) { + 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->getZExtValue()); return ImmReg; } diff --git a/test/CodeGen/PowerPC/fast-isel-ret.ll b/test/CodeGen/PowerPC/fast-isel-ret.ll index eee4f313ee9..e05ef7d9ab8 100644 --- a/test/CodeGen/PowerPC/fast-isel-ret.ll +++ b/test/CodeGen/PowerPC/fast-isel-ret.ll @@ -176,3 +176,13 @@ entry: ; ELF64: blr ret double 2.5e-33; } + +define zeroext i32 @ret19() nounwind { +entry: +; ELF64-LABEL: ret19 +; ELF64: li +; ELF64: oris +; ELF64: ori +; ELF64: blr + ret i32 -1 +} -- 2.34.1