Skip to content

Commit fcabb53

Browse files
[HEXAGON] Add AssertSext in sign-extended mpy (#149061)
The pattern i32xi32->i64, should be matched to the sign-extended multiply op, instead of explicit sign- extension of the operands followed by non-widening multiply (this takes 4 operations instead of one). Currently, if one of the operands of multiply inside a loop is a constant, the sign-extension of this constant is hoisted out of the loop by LICM pass and this pattern is not matched by the ISEL. This change handles multiply operand with Opcode of the type AssertSext which is seen when the sign-extension is hoisted out-of the loop. Modifies the DetectUseSxtw() to check for this.
1 parent fe19419 commit fcabb53

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1640,6 +1640,15 @@ bool HexagonDAGToDAGISel::DetectUseSxtw(SDValue &N, SDValue &R) {
16401640
R = N;
16411641
break;
16421642
}
1643+
case ISD::AssertSext: {
1644+
EVT T = cast<VTSDNode>(N.getOperand(1))->getVT();
1645+
if (T.getSizeInBits() == 32)
1646+
R = N.getOperand(0);
1647+
else
1648+
return false;
1649+
break;
1650+
}
1651+
16431652
default:
16441653
return false;
16451654
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
; RUN: llc -march=hexagon -verify-machineinstrs < %s | FileCheck %s
2+
3+
; CHECK-NOT: r{{[0-9]+}} = asr(r{{[0-9]+}},#{{[0-9]+}})
4+
; CHECK-NOT: r{{[0-9]+}}:{{[0-9]+}} = mpyu(r{{[0-9]+}},r{{[0-9]+}})
5+
; CHECK-NOT: r{{[0-9]+}} += mpyi(r{{[0-9]+}},r{{[0-9]+}})
6+
; CHECK: r{{[0-9]+}}:{{[0-9]+}} = mpy(r{{[0-9]+}},r{{[0-9]+}})
7+
8+
; ModuleID = '39544.c'
9+
source_filename = "39544.c"
10+
target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"
11+
target triple = "hexagon"
12+
13+
define dso_local void @mul_n(i64* nocapture %p, i32* nocapture readonly %a, i32 %k, i32 %n) local_unnamed_addr {
14+
entry:
15+
%cmp7 = icmp sgt i32 %n, 0
16+
br i1 %cmp7, label %for.body.lr.ph, label %for.cond.cleanup
17+
18+
for.body.lr.ph: ; preds = %entry
19+
%conv1 = sext i32 %k to i64
20+
br label %for.body
21+
22+
for.cond.cleanup: ; preds = %for.body, %entry
23+
ret void
24+
25+
for.body: ; preds = %for.body, %for.body.lr.ph
26+
%arrayidx.phi = phi i32* [ %a, %for.body.lr.ph ], [ %arrayidx.inc, %for.body ]
27+
%arrayidx2.phi = phi i64* [ %p, %for.body.lr.ph ], [ %arrayidx2.inc, %for.body ]
28+
%i.08 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
29+
%0 = load i32, i32* %arrayidx.phi, align 4
30+
%conv = sext i32 %0 to i64
31+
%mul = mul nsw i64 %conv, %conv1
32+
store i64 %mul, i64* %arrayidx2.phi, align 8
33+
%inc = add nuw nsw i32 %i.08, 1
34+
%exitcond = icmp eq i32 %inc, %n
35+
%arrayidx.inc = getelementptr i32, i32* %arrayidx.phi, i32 1
36+
%arrayidx2.inc = getelementptr i64, i64* %arrayidx2.phi, i32 1
37+
br i1 %exitcond, label %for.cond.cleanup, label %for.body
38+
}

0 commit comments

Comments
 (0)