[llvm] r216073 - [FastISel][AArch64] Don't fold the sign-/zero-extend from i1 into the compare.

Juergen Ributzka juergen at apple.com
Wed Aug 20 09:34:15 PDT 2014


Author: ributzka
Date: Wed Aug 20 11:34:15 2014
New Revision: 216073

URL: http://llvm.org/viewvc/llvm-project?rev=216073&view=rev
Log:
[FastISel][AArch64] Don't fold the sign-/zero-extend from i1 into the compare.

This fixes a bug I introduced in a previous commit (r216033). Sign-/Zero-
extension from i1 cannot be folded into the ADDS/SUBS instructions. Instead both
operands have to be sign-/zero-extended with separate instructions.

Related to <rdar://problem/17913111>.

Modified:
    llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp
    llvm/trunk/test/CodeGen/AArch64/arm64-fast-isel-icmp.ll

Modified: llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp?rev=216073&r1=216072&r2=216073&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp Wed Aug 20 11:34:15 2014
@@ -773,19 +773,27 @@ unsigned AArch64FastISel::emitAddsSubs(b
                                        const Value *LHS, const Value *RHS,
                                        bool IsZExt, bool WantResult) {
   AArch64_AM::ShiftExtendType ExtendType = AArch64_AM::InvalidShiftExtend;
-  MVT SrcVT = RetVT;
+  bool NeedExtend = false;
   switch (RetVT.SimpleTy) {
-  default: return 0;
+  default:
+    return 0;
   case MVT::i1:
+    NeedExtend = true;
+    break;
   case MVT::i8:
-    ExtendType = IsZExt ? AArch64_AM::UXTB : AArch64_AM::SXTB; RetVT = MVT::i32;
+    NeedExtend = true;
+    ExtendType = IsZExt ? AArch64_AM::UXTB : AArch64_AM::SXTB;
     break;
   case MVT::i16:
-    ExtendType = IsZExt ? AArch64_AM::UXTH : AArch64_AM::SXTH; RetVT = MVT::i32;
+    NeedExtend = true;
+    ExtendType = IsZExt ? AArch64_AM::UXTH : AArch64_AM::SXTH;
+    break;
+  case MVT::i32:  // fall-through
+  case MVT::i64:
     break;
-  case MVT::i32: break;
-  case MVT::i64: break;
   }
+  MVT SrcVT = RetVT;
+  RetVT.SimpleTy = std::max(RetVT.SimpleTy, MVT::i32);
 
   // Canonicalize immediates to the RHS first.
   if (UseAdds && isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS))
@@ -805,7 +813,7 @@ unsigned AArch64FastISel::emitAddsSubs(b
     return 0;
   bool LHSIsKill = hasTrivialKill(LHS);
 
-  if (ExtendType != AArch64_AM::InvalidShiftExtend)
+  if (NeedExtend)
     LHSReg = EmitIntExt(SrcVT, LHSReg, RetVT, IsZExt);
 
   unsigned ResultReg = 0;
@@ -821,6 +829,7 @@ unsigned AArch64FastISel::emitAddsSubs(b
   if (ResultReg)
     return ResultReg;
 
+  // Only extend the RHS within the instruction if there is a valid extend type.
   if (ExtendType != AArch64_AM::InvalidShiftExtend) {
     if (const auto *SI = dyn_cast<BinaryOperator>(RHS))
       if (const auto *C = dyn_cast<ConstantInt>(SI->getOperand(1)))
@@ -867,6 +876,10 @@ unsigned AArch64FastISel::emitAddsSubs(b
   if (!RHSReg)
     return 0;
   bool RHSIsKill = hasTrivialKill(RHS);
+
+  if (NeedExtend)
+    RHSReg = EmitIntExt(SrcVT, RHSReg, RetVT, IsZExt);
+
   return emitAddsSubs_rr(UseAdds, RetVT, LHSReg, LHSIsKill, RHSReg, RHSIsKill,
                          WantResult);
 }

Modified: llvm/trunk/test/CodeGen/AArch64/arm64-fast-isel-icmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-fast-isel-icmp.ll?rev=216073&r1=216072&r2=216073&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/arm64-fast-isel-icmp.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/arm64-fast-isel-icmp.ll Wed Aug 20 11:34:15 2014
@@ -172,6 +172,17 @@ entry:
   ret i32 %conv2
 }
 
+define i32 @icmp_i1_signed(i1 %a, i1 %b) nounwind {
+entry:
+; CHECK-LABEL: icmp_i1_signed
+; CHECK:       sbfx [[REG1:w[0-9]+]], w0, #0, #1
+; CHECK-NEXT:  sbfx [[REG2:w[0-9]+]], w1, #0, #1
+; CHECK-NEXT:  cmp  [[REG1]], [[REG2]]
+; CHECK-NEXT:  cset w0, gt
+  %cmp = icmp sgt i1 %a, %b
+  %conv2 = zext i1 %cmp to i32
+  ret i32 %conv2
+}
 
 define i32 @icmp_i16_signed_const(i16 %a) nounwind {
 entry:





More information about the llvm-commits mailing list