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
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"));
Expand Down Expand Up @@ -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,
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
57 changes: 57 additions & 0 deletions llvm/test/CodeGen/Hexagon/hexagon-strcpy.ll
Original file line number Diff line number Diff line change
@@ -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)
Loading