Fix PPCMaterializeInt to check the size of the integer based on the
authorEric Christopher <echristo@gmail.com>
Sat, 25 Jul 2015 00:48:08 +0000 (00:48 +0000)
committerEric Christopher <echristo@gmail.com>
Sat, 25 Jul 2015 00:48:08 +0000 (00:48 +0000)
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
test/CodeGen/PowerPC/fast-isel-ret.ll

index 7c184f4bdd0969e7e4e4444e99ee9a23b23fb206..700df20f8aa07e9c3bfb4a8cad6f4e646fc0b23a 100644 (file)
@@ -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<ConstantInt>(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;
   }
 
index eee4f313ee9603d9a120c38a558e026dfc080d6d..e05ef7d9ab82477832ff00cbd71fde25270c7453 100644 (file)
@@ -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
+}