Fix for PR 26356
authorNemanja Ivanovic <nemanja.i.ibm@gmail.com>
Thu, 4 Feb 2016 23:14:42 +0000 (23:14 +0000)
committerNemanja Ivanovic <nemanja.i.ibm@gmail.com>
Thu, 4 Feb 2016 23:14:42 +0000 (23:14 +0000)
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
llvm/test/CodeGen/PowerPC/pr26356.ll [new file with mode: 0644]

index 795fd6d..3980ecf 100644 (file)
@@ -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 (file)
index 0000000..0f5d877
--- /dev/null
@@ -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