Merging r259840 on top of r259178:
authorHans Wennborg <hans@hanshq.net>
Fri, 5 Feb 2016 00:55:39 +0000 (00:55 +0000)
committerHans Wennborg <hans@hanshq.net>
Fri, 5 Feb 2016 00:55:39 +0000 (00:55 +0000)
------------------------------------------------------------------------
r259178 | echristo | 2016-01-28 23:20:30 -0800 (Thu, 28 Jan 2016) | 1 line

Refactor common code for PPC fast isel load immediate selection.
------------------------------------------------------------------------

------------------------------------------------------------------------
r259840 | nemanjai | 2016-02-04 15:14:42 -0800 (Thu, 04 Feb 2016) | 7 lines

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.
------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_38@259858 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/PPCFastISel.cpp
test/CodeGen/PowerPC/pr26356.ll [new file with mode: 0644]

index 777cc3b601c0742c523c8f9f05cb7fde8044d81d..16dcd468c91d60ecf96ba3775ba8609af54fbc7d 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);
@@ -2091,26 +2091,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.
-  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(CI->getSExtValue());
-    return ImmReg;
-  } else if (!UseSExt && isUInt<16>(CI->getSExtValue())) {
-    // 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.
+  // 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 (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->getZExtValue());
+        .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 (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