diff --git a/lib/Target/PowerPC/PPCFastISel.cpp b/lib/Target/PowerPC/PPCFastISel.cpp index 795fd6d0b7a..3980ecfac77 100644 --- a/lib/Target/PowerPC/PPCFastISel.cpp +++ b/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/test/CodeGen/PowerPC/pr26356.ll b/test/CodeGen/PowerPC/pr26356.ll new file mode 100644 index 00000000000..0f5d877b576 --- /dev/null +++ b/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