ARM: only form SMMLS when SUBE flags unused.

In this particular example we wouldn't want the smmls anyway (the value is
actually unused), but in general smmls does not provide the required flags
register so if that SUBE result is used we can't replace it.

llvm-svn: 277541
This commit is contained in:
Tim Northover 2016-08-02 23:12:36 +00:00
parent 395cc09444
commit 765777ce67
2 changed files with 23 additions and 1 deletions

View File

@ -3047,7 +3047,8 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
// Look for a pattern to match SMMLS
// (sube a, (smul_loHi a, b), (subc 0, (smul_LOhi(a, b))))
if (N->getOperand(1).getOpcode() != ISD::SMUL_LOHI ||
N->getOperand(2).getOpcode() != ARMISD::SUBC)
N->getOperand(2).getOpcode() != ARMISD::SUBC ||
!SDValue(N, 1).use_empty())
break;
if (Subtarget->isThumb())

View File

@ -44,3 +44,24 @@ entry:
%conv3 = trunc i64 %shr7 to i32
ret i32 %conv3
}
declare void @opaque(i32)
define void @test_used_flags(i32 %in1, i32 %in2) {
; CHECK-V7-LABEL: test_used_flags:
; CHECK-V7: smull [[PROD_LO:r[0-9]+]], [[PROD_HI:r[0-9]+]], r0, r1
; CHECK-V7: rsbs {{.*}}, [[PROD_LO]], #0
; CHECK-V7: rscs {{.*}}, [[PROD_HI]], #0
%in1.64 = sext i32 %in1 to i64
%in2.64 = sext i32 %in2 to i64
%mul = mul nsw i64 %in1.64, %in2.64
%tst = icmp slt i64 %mul, 1
br i1 %tst, label %true, label %false
true:
call void @opaque(i32 42)
ret void
false:
call void @opaque(i32 56)
ret void
}