From 5273295751756f4537aad691cdb8a155a74db7ae Mon Sep 17 00:00:00 2001 From: Juergen Ributzka Date: Wed, 20 Aug 2014 16:34:15 +0000 Subject: [PATCH] [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 . git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216073 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64FastISel.cpp | 27 +++++++++++++++----- test/CodeGen/AArch64/arm64-fast-isel-icmp.ll | 11 ++++++++ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/lib/Target/AArch64/AArch64FastISel.cpp b/lib/Target/AArch64/AArch64FastISel.cpp index 7320bb89dc4..1bc5e424eac 100644 --- a/lib/Target/AArch64/AArch64FastISel.cpp +++ b/lib/Target/AArch64/AArch64FastISel.cpp @@ -773,19 +773,27 @@ unsigned AArch64FastISel::emitAddsSubs(bool UseAdds, MVT RetVT, 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(LHS) && !isa(RHS)) @@ -805,7 +813,7 @@ unsigned AArch64FastISel::emitAddsSubs(bool UseAdds, MVT RetVT, 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(bool UseAdds, MVT RetVT, 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(RHS)) if (const auto *C = dyn_cast(SI->getOperand(1))) @@ -867,6 +876,10 @@ unsigned AArch64FastISel::emitAddsSubs(bool UseAdds, MVT RetVT, 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); } diff --git a/test/CodeGen/AArch64/arm64-fast-isel-icmp.ll b/test/CodeGen/AArch64/arm64-fast-isel-icmp.ll index bd1666bfb84..e0d7d413166 100644 --- a/test/CodeGen/AArch64/arm64-fast-isel-icmp.ll +++ b/test/CodeGen/AArch64/arm64-fast-isel-icmp.ll @@ -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: