Skip to content

[HEXAGON] Add AssertSext in sign-extended mpy#149061

Merged
quic-asaravan merged 1 commit into
llvm:mainfrom
quic-asaravan:Mul_Improv
Jul 17, 2025
Merged

[HEXAGON] Add AssertSext in sign-extended mpy#149061
quic-asaravan merged 1 commit into
llvm:mainfrom
quic-asaravan:Mul_Improv

Conversation

@quic-asaravan

@quic-asaravan quic-asaravan commented Jul 16, 2025

Copy link
Copy Markdown
Contributor

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.

Co-authored-by: Shubham Pawar

@quic-asaravan quic-asaravan marked this pull request as ready for review July 16, 2025 12:57
@llvmbot

llvmbot commented Jul 16, 2025

Copy link
Copy Markdown
Member

@llvm/pr-subscribers-backend-hexagon

Author: Abinaya Saravanan (quic-asaravan)

Changes

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.

Co-authored-by: Shubham Pawar


Full diff: https://github.com/llvm/llvm-project/pull/149061.diff

2 Files Affected:

  • (modified) llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp (+9)
  • (added) llvm/test/CodeGen/Hexagon/mpy-operand-hoist.ll (+38)
diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
index 53943de3bc597..e285e04543694 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
@@ -1640,6 +1640,15 @@ bool HexagonDAGToDAGISel::DetectUseSxtw(SDValue &N, SDValue &R) {
       R = N;
       break;
     }
+    case ISD::AssertSext: {
+      EVT T = cast<VTSDNode>(N.getOperand(1))->getVT();
+      if (T.getSizeInBits() == 32)
+        R = N.getOperand(0);
+      else
+        return false;
+      break;
+    }
+
     default:
       return false;
   }
diff --git a/llvm/test/CodeGen/Hexagon/mpy-operand-hoist.ll b/llvm/test/CodeGen/Hexagon/mpy-operand-hoist.ll
new file mode 100644
index 0000000000000..ff50f1abe5897
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/mpy-operand-hoist.ll
@@ -0,0 +1,38 @@
+; RUN: llc -march=hexagon -verify-machineinstrs < %s | FileCheck %s
+
+; CHECK-NOT: r{{[0-9]+}} = asr(r{{[0-9]+}},#{{[0-9]+}})
+; CHECK-NOT: r{{[0-9]+}}:{{[0-9]+}} = mpyu(r{{[0-9]+}},r{{[0-9]+}})
+; CHECK-NOT: r{{[0-9]+}} += mpyi(r{{[0-9]+}},r{{[0-9]+}})
+; CHECK: r{{[0-9]+}}:{{[0-9]+}} = mpy(r{{[0-9]+}},r{{[0-9]+}})
+
+; ModuleID = '39544.c'
+source_filename = "39544.c"
+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"
+target triple = "hexagon"
+
+define dso_local void @mul_n(i64* nocapture %p, i32* nocapture readonly %a, i32 %k, i32 %n) local_unnamed_addr {
+entry:
+  %cmp7 = icmp sgt i32 %n, 0
+  br i1 %cmp7, label %for.body.lr.ph, label %for.cond.cleanup
+
+for.body.lr.ph:                                   ; preds = %entry
+  %conv1 = sext i32 %k to i64
+  br label %for.body
+
+for.cond.cleanup:                                 ; preds = %for.body, %entry
+  ret void
+
+for.body:                                         ; preds = %for.body, %for.body.lr.ph
+  %arrayidx.phi = phi i32* [ %a, %for.body.lr.ph ], [ %arrayidx.inc, %for.body ]
+  %arrayidx2.phi = phi i64* [ %p, %for.body.lr.ph ], [ %arrayidx2.inc, %for.body ]
+  %i.08 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
+  %0 = load i32, i32* %arrayidx.phi, align 4
+  %conv = sext i32 %0 to i64
+  %mul = mul nsw i64 %conv, %conv1
+  store i64 %mul, i64* %arrayidx2.phi, align 8
+  %inc = add nuw nsw i32 %i.08, 1
+  %exitcond = icmp eq i32 %inc, %n
+  %arrayidx.inc = getelementptr i32, i32* %arrayidx.phi, i32 1
+  %arrayidx2.inc = getelementptr i64, i64* %arrayidx2.phi, i32 1
+  br i1 %exitcond, label %for.cond.cleanup, label %for.body
+}

@quic-asaravan

quic-asaravan commented Jul 16, 2025

Copy link
Copy Markdown
Contributor Author

@aankit-ca @svs-quic @SundeepKushwaha @androm3da Can you review this please?

@svs-quic svs-quic left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! The co-authored line needs to include the email id of the co-author as well. If one isn't available then I would suggest just removing it.

Please refer to https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors

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.
@quic-asaravan quic-asaravan merged commit fcabb53 into llvm:main Jul 17, 2025
9 checks passed
@quic-asaravan quic-asaravan deleted the Mul_Improv branch July 18, 2025 04:58
@svs-quic

Copy link
Copy Markdown
Contributor

/cherry-pick fcabb53

@llvmbot

llvmbot commented Jul 21, 2025

Copy link
Copy Markdown
Member

/cherry-pick fcabb53

Error: Command failed due to missing milestone.

@svs-quic

Copy link
Copy Markdown
Contributor

/cherry-pick fcabb53

@llvmbot

llvmbot commented Jul 21, 2025

Copy link
Copy Markdown
Member

/cherry-pick fcabb53

Error: Command failed due to missing milestone.

@svs-quic

Copy link
Copy Markdown
Contributor

/cherry-pick fcabb53

@llvmbot

llvmbot commented Jul 21, 2025

Copy link
Copy Markdown
Member

/pull-request #149773

@llvmbot llvmbot moved this from Needs Triage to Done in LLVM Release Status Jul 21, 2025
tru pushed a commit to llvmbot/llvm-project that referenced this pull request Jul 22, 2025
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.

(cherry picked from commit fcabb53)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Development

Successfully merging this pull request may close these issues.

3 participants