Skip to content

[Hexagon] Implement shouldConvertConstantLoadToIntImm #146452

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 1, 2025

Conversation

svs-quic
Copy link
Contributor

@svs-quic svs-quic commented Jul 1, 2025

This will convert loads of constant strings to immediate values. Put this behind a flag that is enabled by default so that we can toggle it if need be.

svs-quic added 2 commits July 1, 2025 07:29
This will convert loads of constant strings to immediate values. Put this
behind a flag that is enabled by default so that we can toggle it if need be.
@llvmbot
Copy link
Member

llvmbot commented Jul 1, 2025

@llvm/pr-subscribers-backend-hexagon

Author: Sudharsan Veeravalli (svs-quic)

Changes

This will convert loads of constant strings to immediate values. Put this behind a flag that is enabled by default so that we can toggle it if need be.


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

3 Files Affected:

  • (modified) llvm/lib/Target/Hexagon/HexagonISelLowering.cpp (+16)
  • (modified) llvm/lib/Target/Hexagon/HexagonISelLowering.h (+5)
  • (added) llvm/test/CodeGen/Hexagon/hexagon-strcpy.ll (+57)
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
index 6534ae938fede..e7d0ec6ee0fe5 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
@@ -102,6 +102,10 @@ static cl::opt<int>
     MaxStoresPerMemsetOptSizeCL("max-store-memset-Os", cl::Hidden, cl::init(4),
                                 cl::desc("Max #stores to inline memset"));
 
+static cl::opt<bool>
+    ConstantLoadsToImm("constant-loads-to-imm", cl::Hidden, cl::init(true),
+                       cl::desc("Convert constant loads to immediate values."));
+
 static cl::opt<bool> AlignLoads("hexagon-align-loads",
   cl::Hidden, cl::init(false),
   cl::desc("Rewrite unaligned loads as a pair of aligned loads"));
@@ -3607,6 +3611,18 @@ bool HexagonTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
   return true;
 }
 
+/// Returns true if it is beneficial to convert a load of a constant
+/// to just the constant itself.
+bool HexagonTargetLowering::shouldConvertConstantLoadToIntImm(const APInt &Imm,
+                                                              Type *Ty) const {
+  if (!ConstantLoadsToImm)
+    return false;
+
+  assert(Ty->isIntegerTy());
+  unsigned BitSize = Ty->getPrimitiveSizeInBits();
+  return (BitSize > 0 && BitSize <= 64);
+}
+
 /// isLegalAddressingMode - Return true if the addressing mode represented by
 /// AM is legal for this target, for a load/store of the specified type.
 bool HexagonTargetLowering::isLegalAddressingMode(const DataLayout &DL,
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.h b/llvm/lib/Target/Hexagon/HexagonISelLowering.h
index 1321bee44a295..a2c9b57d04caa 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.h
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.h
@@ -342,6 +342,11 @@ class HexagonTargetLowering : public TargetLowering {
   SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG)
                                    const override;
 
+  /// Returns true if it is beneficial to convert a load of a constant
+  /// to just the constant itself.
+  bool shouldConvertConstantLoadToIntImm(const APInt &Imm,
+                                         Type *Ty) const override;
+
   bool shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtTy, EVT NewVT,
                              std::optional<unsigned> ByteOffset) const override;
 
diff --git a/llvm/test/CodeGen/Hexagon/hexagon-strcpy.ll b/llvm/test/CodeGen/Hexagon/hexagon-strcpy.ll
new file mode 100644
index 0000000000000..b23366bc11aca
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/hexagon-strcpy.ll
@@ -0,0 +1,57 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -march=hexagon -verify-machineinstrs  < %s | FileCheck %s
+
+@.str = private unnamed_addr constant [31 x i8] c"DHRYSTONE PROGRAM, 3'RD STRING\00", align 1
+@.str1 = private unnamed_addr constant [3 x i8] c"%s\00", align 1
+
+; Function Attrs: nounwind
+declare i32 @printf(i8* nocapture readonly, ...)
+
+; Function Attrs: nounwind
+define i32 @main() {
+; CHECK-LABEL: main:
+; CHECK:         .cfi_startproc
+; CHECK-NEXT:  // %bb.0: // %entry
+; CHECK-NEXT:    .cfi_def_cfa r30, 8
+; CHECK-NEXT:    .cfi_offset r31, -4
+; CHECK-NEXT:    .cfi_offset r30, -8
+; CHECK-NEXT:    {
+; CHECK-NEXT:     r0 = ##.L.str1
+; CHECK-NEXT:     r3:2 = CONST64(#2325073635944967245)
+; CHECK-NEXT:     allocframe(r29,#40):raw
+; CHECK-NEXT:    }
+; CHECK-NEXT:    {
+; CHECK-NEXT:     r1 = add(r29,#8)
+; CHECK-NEXT:     r7:6 = CONST64(#4706902966564560965)
+; CHECK-NEXT:     r5:4 = CONST64(#5642821575076104260)
+; CHECK-NEXT:    }
+; CHECK-NEXT:    {
+; CHECK-NEXT:     memb(r29+#38) = #0
+; CHECK-NEXT:     memw(r29+#0) = r1
+; CHECK-NEXT:    }
+; CHECK-NEXT:    {
+; CHECK-NEXT:     memd(r29+#24) = r3:2
+; CHECK-NEXT:     memd(r29+#16) = r7:6
+; CHECK-NEXT:    }
+; CHECK-NEXT:    {
+; CHECK-NEXT:     memd(r29+#8) = r5:4
+; CHECK-NEXT:     memh(r29+#36) = ##18254
+; CHECK-NEXT:    }
+; CHECK-NEXT:    {
+; CHECK-NEXT:     call printf
+; CHECK-NEXT:     memw(r29+#32) = ##1230132307
+; CHECK-NEXT:    }
+; CHECK-NEXT:    {
+; CHECK-NEXT:     r0 = #0
+; CHECK-NEXT:     dealloc_return
+; CHECK-NEXT:    }
+entry:
+  %blah = alloca [30 x i8], align 8
+  %arraydecay = getelementptr inbounds [30 x i8], [30 x i8]* %blah, i32 0, i32 0
+  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %arraydecay, i8* getelementptr inbounds ([31 x i8], [31 x i8]* @.str, i32 0, i32 0), i32 31, i32 1, i1 false)
+  %call2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str1, i32 0, i32 0), i8* %arraydecay)
+  ret i32 0
+}
+
+; Function Attrs: nounwind
+declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1)

Copy link
Contributor

@aankit-ca aankit-ca left a comment

Choose a reason for hiding this comment

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

LGTM

@svs-quic svs-quic merged commit 15ab4bb into llvm:main Jul 1, 2025
9 checks passed
@svs-quic svs-quic deleted the hex_constloadimm branch July 1, 2025 12:22
rlavaee pushed a commit to rlavaee/llvm-project that referenced this pull request Jul 1, 2025
This will convert loads of constant strings to immediate values. Put
this behind a flag that is enabled by default so that we can toggle it
if need be.
rlavaee pushed a commit to rlavaee/llvm-project that referenced this pull request Jul 1, 2025
This will convert loads of constant strings to immediate values. Put
this behind a flag that is enabled by default so that we can toggle it
if need be.
@fossdd
Copy link
Contributor

fossdd commented Jul 30, 2025

Hi, this commit currently leads to a test fail with 21-rc1 and -rc2 on Alpine Linux edge on most architectures:

FAIL: LLVM :: Transforms/MemProfContextDisambiguation/dot.ll (49321 of 58891)
******************** TEST 'LLVM :: Transforms/MemProfContextDisambiguation/dot.ll' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
not --crash /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/bin/opt -passes=memprof-context-disambiguation -supports-hot-cold-new    -memprof-export-to-dot -memprof-dot-file-path-prefix=/builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/test/Transforms/MemProfContextDisambiguation/Output/dot.ll.tmp.         -memprof-dot-scope=alloc     /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/llvm/test/Transforms/MemProfContextDisambiguation/dot.ll -S 2>&1 | /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/bin/FileCheck /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/llvm/test/Transforms/MemProfContextDisambiguation/dot.ll --check-prefix=ERRMISSINGALLOCID # RUN: at line 6
+ not --crash /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/bin/opt -passes=memprof-context-disambiguation -supports-hot-cold-new -memprof-export-to-dot -memprof-dot-file-path-prefix=/builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/test/Transforms/MemProfContextDisambiguation/Output/dot.ll.tmp. -memprof-dot-scope=alloc /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/llvm/test/Transforms/MemProfContextDisambiguation/dot.ll -S
+ /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/bin/FileCheck /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/llvm/test/Transforms/MemProfContextDisambiguation/dot.ll --check-prefix=ERRMISSINGALLOCID
not --crash /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/bin/opt -passes=memprof-context-disambiguation -supports-hot-cold-new    -memprof-export-to-dot -memprof-dot-file-path-prefix=/builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/test/Transforms/MemProfContextDisambiguation/Output/dot.ll.tmp.         -memprof-dot-scope=context   /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/llvm/test/Transforms/MemProfContextDisambiguation/dot.ll -S 2>&1 | /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/bin/FileCheck /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/llvm/test/Transforms/MemProfContextDisambiguation/dot.ll --check-prefix=ERRMISSINGCONTEXTID # RUN: at line 13
+ not --crash /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/bin/opt -passes=memprof-context-disambiguation -supports-hot-cold-new -memprof-export-to-dot -memprof-dot-file-path-prefix=/builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/test/Transforms/MemProfContextDisambiguation/Output/dot.ll.tmp. -memprof-dot-scope=context /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/llvm/test/Transforms/MemProfContextDisambiguation/dot.ll -S
+ /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/bin/FileCheck /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/llvm/test/Transforms/MemProfContextDisambiguation/dot.ll --check-prefix=ERRMISSINGCONTEXTID
not --crash /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/bin/opt -passes=memprof-context-disambiguation -supports-hot-cold-new    -memprof-export-to-dot -memprof-dot-file-path-prefix=/builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/test/Transforms/MemProfContextDisambiguation/Output/dot.ll.tmp.         -memprof-dot-alloc-id=0 -memprof-dot-context-id=2    /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/llvm/test/Transforms/MemProfContextDisambiguation/dot.ll -S 2>&1 | /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/bin/FileCheck /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/llvm/test/Transforms/MemProfContextDisambiguation/dot.ll --check-prefix=ERRBOTH # RUN: at line 21
+ not --crash /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/bin/opt -passes=memprof-context-disambiguation -supports-hot-cold-new -memprof-export-to-dot -memprof-dot-file-path-prefix=/builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/test/Transforms/MemProfContextDisambiguation/Output/dot.ll.tmp. -memprof-dot-alloc-id=0 -memprof-dot-context-id=2 /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/llvm/test/Transforms/MemProfContextDisambiguation/dot.ll -S
+ /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/bin/FileCheck /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/llvm/test/Transforms/MemProfContextDisambiguation/dot.ll --check-prefix=ERRBOTH
/builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/bin/opt -passes=memprof-context-disambiguation -supports-hot-cold-new        -memprof-export-to-dot -memprof-dot-file-path-prefix=/builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/test/Transforms/MemProfContextDisambiguation/Output/dot.ll.tmp.         /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/llvm/test/Transforms/MemProfContextDisambiguation/dot.ll -S 2>&1 | /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/bin/FileCheck /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/llvm/test/Transforms/MemProfContextDisambiguation/dot.ll --check-prefix=IR # RUN: at line 28
+ /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/bin/opt -passes=memprof-context-disambiguation -supports-hot-cold-new -memprof-export-to-dot -memprof-dot-file-path-prefix=/builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/test/Transforms/MemProfContextDisambiguation/Output/dot.ll.tmp. /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/llvm/test/Transforms/MemProfContextDisambiguation/dot.ll -S
+ /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/bin/FileCheck /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/llvm/test/Transforms/MemProfContextDisambiguation/dot.ll --check-prefix=IR
cat /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/test/Transforms/MemProfContextDisambiguation/Output/dot.ll.tmp.ccg.postbuild.dot | /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/bin/FileCheck /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/llvm/test/Transforms/MemProfContextDisambiguation/dot.ll -check-prefix=DOTCOMMON --check-prefix=DOTALLANDALLOC0 --check-prefix=DOTALL --check-prefix=DOTALLNONE # RUN: at line 31
+ cat /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/test/Transforms/MemProfContextDisambiguation/Output/dot.ll.tmp.ccg.postbuild.dot
+ /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/build/bin/FileCheck /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/llvm/test/Transforms/MemProfContextDisambiguation/dot.ll -check-prefix=DOTCOMMON --check-prefix=DOTALLANDALLOC0 --check-prefix=DOTALL --check-prefix=DOTALLNONE
/builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/llvm/test/Transforms/MemProfContextDisambiguation/dot.ll:166:14: error: DOTCOMMON: expected string not found in input
; DOTCOMMON: Node[[BAR:0x[a-z0-9]+]] [shape=record,tooltip="N[[BAR]] ContextIds: 1 2",
             ^
<stdin>:1:1: note: scanning from here
digraph "postbuild" {
^
<stdin>:4:2: note: possible intended match here
 Node0xf7672c10 [shape=record,tooltip="N0xfffffffff7672c10 ContextIds: 1 2",fillcolor="mediumorchid1",style="filled",label="{OrigId: Alloc0\n_Z3barv -\> _Znam}"];
 ^

Input file: <stdin>
Check file: /builds/alpine/aports/testing/llvm21/src/llvm-project-21.1.0-rc2.src/llvm/test/Transforms/MemProfContextDisambiguation/dot.ll

-dump-input=help explains the following input dump.

Input was:
<<<<<<
             1: digraph "postbuild" { 
check:166'0     X~~~~~~~~~~~~~~~~~~~~~ error: no match found
             2:  label="postbuild"; 
check:166'0     ~~~~~~~~~~~~~~~~~~~~
             3:  
check:166'0     ~
             4:  Node0xf7672c10 [shape=record,tooltip="N0xfffffffff7672c10 ContextIds: 1 2",fillcolor="mediumorchid1",style="filled",label="{OrigId: Alloc0\n_Z3barv -\> _Znam}"]; 
check:166'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
check:166'1      ?                                                                                                                                                                  possible intended match
             5:  Node0xf7672c60 [shape=record,tooltip="N0xfffffffff7672c60 ContextIds: 1 2 3 4",fillcolor="mediumorchid1",style="filled",label="{OrigId: 12481870273128938184\n_Z3bazv -\> _Z3barv}"]; 
check:166'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             6:  Node0xf7672c60 -> Node0xf7672c10[tooltip="ContextIds: 1 2",fillcolor="mediumorchid1",color="mediumorchid1"]; 
check:166'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             7:  Node0xf7672c60 -> Node0xf76725f0[tooltip="ContextIds: 3 4",fillcolor="mediumorchid1",color="mediumorchid1"]; 
check:166'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             8:  Node0xf7672cb0 [shape=record,tooltip="N0xfffffffff7672cb0 ContextIds: 1 2 3 4",fillcolor="mediumorchid1",style="filled",label="{OrigId: 2732490490862098848\n_Z3foov -\> _Z3bazv}"]; 
check:166'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             9:  Node0xf7672cb0 -> Node0xf7672c60[tooltip="ContextIds: 1 2 3 4",fillcolor="mediumorchid1",color="mediumorchid1"]; 
check:166'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             .
             .
             .
>>>>>>

Do you understand whats going on here?

@svs-quic
Copy link
Contributor Author

It's been almost a month since this got merged. It looks like there is a change in the order of the cfi instructions emitted in the test case. Do you have a buildbot link for this? I'm not sure if there was another patch that caused this change.

@fossdd
Copy link
Contributor

fossdd commented Jul 30, 2025

I have a gitlab CI build link for the build log https://gitlab.alpinelinux.org/alpine/aports/-/jobs/1953786 (raw: https://gitlab.alpinelinux.org/alpine/aports/-/jobs/1953786/raw, relevant error at line 7461).

For -rc1 i simply reverted this patch and it succeeded, i'm currently trying to do the same for -rc2.

@svs-quic
Copy link
Contributor Author

I've pushed #151293 to remove the cfi information from the test checks. Can you let me know if the failure goes away with that?

@svs-quic
Copy link
Contributor Author

@fossdd I have merged #151293 on main. Could you please try applying the patch and let me know if the failure goes away?

@fossdd
Copy link
Contributor

fossdd commented Jul 31, 2025

Yes indeed that fixes the test, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants