forked from OSchip/llvm-project
[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>. llvm-svn: 216073
This commit is contained in:
parent
208faaaa29
commit
e1bb055ed3
|
@ -773,19 +773,27 @@ unsigned AArch64FastISel::emitAddsSubs(bool UseAdds, MVT RetVT,
|
||||||
const Value *LHS, const Value *RHS,
|
const Value *LHS, const Value *RHS,
|
||||||
bool IsZExt, bool WantResult) {
|
bool IsZExt, bool WantResult) {
|
||||||
AArch64_AM::ShiftExtendType ExtendType = AArch64_AM::InvalidShiftExtend;
|
AArch64_AM::ShiftExtendType ExtendType = AArch64_AM::InvalidShiftExtend;
|
||||||
MVT SrcVT = RetVT;
|
bool NeedExtend = false;
|
||||||
switch (RetVT.SimpleTy) {
|
switch (RetVT.SimpleTy) {
|
||||||
default: return 0;
|
default:
|
||||||
|
return 0;
|
||||||
case MVT::i1:
|
case MVT::i1:
|
||||||
|
NeedExtend = true;
|
||||||
|
break;
|
||||||
case MVT::i8:
|
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;
|
break;
|
||||||
case MVT::i16:
|
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;
|
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.
|
// Canonicalize immediates to the RHS first.
|
||||||
if (UseAdds && isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS))
|
if (UseAdds && isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS))
|
||||||
|
@ -805,7 +813,7 @@ unsigned AArch64FastISel::emitAddsSubs(bool UseAdds, MVT RetVT,
|
||||||
return 0;
|
return 0;
|
||||||
bool LHSIsKill = hasTrivialKill(LHS);
|
bool LHSIsKill = hasTrivialKill(LHS);
|
||||||
|
|
||||||
if (ExtendType != AArch64_AM::InvalidShiftExtend)
|
if (NeedExtend)
|
||||||
LHSReg = EmitIntExt(SrcVT, LHSReg, RetVT, IsZExt);
|
LHSReg = EmitIntExt(SrcVT, LHSReg, RetVT, IsZExt);
|
||||||
|
|
||||||
unsigned ResultReg = 0;
|
unsigned ResultReg = 0;
|
||||||
|
@ -821,6 +829,7 @@ unsigned AArch64FastISel::emitAddsSubs(bool UseAdds, MVT RetVT,
|
||||||
if (ResultReg)
|
if (ResultReg)
|
||||||
return ResultReg;
|
return ResultReg;
|
||||||
|
|
||||||
|
// Only extend the RHS within the instruction if there is a valid extend type.
|
||||||
if (ExtendType != AArch64_AM::InvalidShiftExtend) {
|
if (ExtendType != AArch64_AM::InvalidShiftExtend) {
|
||||||
if (const auto *SI = dyn_cast<BinaryOperator>(RHS))
|
if (const auto *SI = dyn_cast<BinaryOperator>(RHS))
|
||||||
if (const auto *C = dyn_cast<ConstantInt>(SI->getOperand(1)))
|
if (const auto *C = dyn_cast<ConstantInt>(SI->getOperand(1)))
|
||||||
|
@ -867,6 +876,10 @@ unsigned AArch64FastISel::emitAddsSubs(bool UseAdds, MVT RetVT,
|
||||||
if (!RHSReg)
|
if (!RHSReg)
|
||||||
return 0;
|
return 0;
|
||||||
bool RHSIsKill = hasTrivialKill(RHS);
|
bool RHSIsKill = hasTrivialKill(RHS);
|
||||||
|
|
||||||
|
if (NeedExtend)
|
||||||
|
RHSReg = EmitIntExt(SrcVT, RHSReg, RetVT, IsZExt);
|
||||||
|
|
||||||
return emitAddsSubs_rr(UseAdds, RetVT, LHSReg, LHSIsKill, RHSReg, RHSIsKill,
|
return emitAddsSubs_rr(UseAdds, RetVT, LHSReg, LHSIsKill, RHSReg, RHSIsKill,
|
||||||
WantResult);
|
WantResult);
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,6 +172,17 @@ entry:
|
||||||
ret i32 %conv2
|
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 {
|
define i32 @icmp_i16_signed_const(i16 %a) nounwind {
|
||||||
entry:
|
entry:
|
||||||
|
|
Loading…
Reference in New Issue