[llvm] [ARM] Enable promoteToConstantPool if only one use. (PR #125065)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 30 06:52:10 PST 2025


https://github.com/walkerkd created https://github.com/llvm/llvm-project/pull/125065

If a global constant has only one use, then it is safe to promote it to a constant pool.

This improves the code for the one use cases, until issue #32127 is fixed to also allow the promotion when it is safe if there are multiple uses.

>From 0e912b7c62c8524dac915878b1f5a2c64dc42aaf Mon Sep 17 00:00:00 2001
From: Keith Walker <keith.walker at arm.com>
Date: Thu, 30 Jan 2025 13:52:50 +0000
Subject: [PATCH] [ARM] Enable promoteToConstantPool if only one use.

If a global constant has only one use, then it is safe to promote
it to a constant pool.

This improves the code for the one use cases, until issue #32127
is fixed to also allow the promotion when it is safe if there are
multiple uses.
---
 llvm/lib/Target/ARM/ARMISelLowering.cpp       | 38 +++++++++++++++++--
 .../CodeGen/ARM/arm-shrink-wrapping-linux.ll  | 26 ++++++++-----
 llvm/test/CodeGen/ARM/constantpool-promote.ll |  6 +--
 llvm/test/CodeGen/ARM/memcpy-inline.ll        | 26 ++++++++-----
 .../CodeGen/Thumb2/bti-indirect-branches.ll   |  9 ++++-
 5 files changed, 76 insertions(+), 29 deletions(-)

diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index bd8d6079e1ba88..8a7cc4c07052f0 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -134,7 +134,7 @@ static cl::opt<bool> EnableConstpoolPromotion(
     "arm-promote-constant", cl::Hidden,
     cl::desc("Enable / disable promotion of unnamed_addr constants into "
              "constant pools"),
-    cl::init(false)); // FIXME: set to true by default once PR32780 is fixed
+    cl::init(true));
 static cl::opt<unsigned> ConstpoolPromotionMaxSize(
     "arm-promote-constant-max-size", cl::Hidden,
     cl::desc("Maximum size of constant to promote into a constant pool"),
@@ -3905,6 +3905,36 @@ static bool allUsersAreInFunction(const Value *V, const Function *F) {
   return true;
 }
 
+// Until issue #32127 is fixed allow the simple case
+// when there is only one use.
+static bool hasOnlyOneUse(const GlobalValue *GV) {
+  if (GV->hasNUsesOrMore(2))
+    return false;
+
+  SmallVector<const User *, 4> Worklist;
+  for (auto *U : GV->users()) {
+    // Be safe. If we cast, don't promote
+    if (isa<BitCastOperator>(U) || isa<PtrToIntOperator>(U))
+      return false;
+    if (isa<ConstantExpr>(U) || isa<GEPOperator>(U))
+      Worklist.push_back(U);
+  }
+  while (!Worklist.empty()) {
+    auto *U = Worklist.pop_back_val();
+    if (U->hasNUsesOrMore(2))
+      return false;
+
+    for (auto *UU : U->users()) {
+      // Be safe. If we cast, don't promote
+      if (isa<BitCastOperator>(UU) || isa<PtrToIntOperator>(UU))
+        return false;
+      if (isa<ConstantExpr>(UU) || isa<GEPOperator>(UU))
+        Worklist.push_back(UU);
+    }
+  }
+  return true;
+}
+
 static SDValue promoteToConstantPool(const ARMTargetLowering *TLI,
                                      const GlobalValue *GV, SelectionDAG &DAG,
                                      EVT PtrVT, const SDLoc &dl) {
@@ -3928,9 +3958,9 @@ static SDValue promoteToConstantPool(const ARMTargetLowering *TLI,
       return SDValue();
 
   auto *GVar = dyn_cast<GlobalVariable>(GV);
-  if (!GVar || !GVar->hasInitializer() ||
-      !GVar->isConstant() || !GVar->hasGlobalUnnamedAddr() ||
-      !GVar->hasLocalLinkage())
+  if (!GVar || !GVar->hasInitializer() || !GVar->isConstant() ||
+      !GVar->hasGlobalUnnamedAddr() || !GVar->hasLocalLinkage() ||
+      !hasOnlyOneUse(GVar))
     return SDValue();
 
   // If we inline a value that contains relocations, we move the relocations
diff --git a/llvm/test/CodeGen/ARM/arm-shrink-wrapping-linux.ll b/llvm/test/CodeGen/ARM/arm-shrink-wrapping-linux.ll
index f367a5626c8d3c..ff9f163a69de97 100644
--- a/llvm/test/CodeGen/ARM/arm-shrink-wrapping-linux.ll
+++ b/llvm/test/CodeGen/ARM/arm-shrink-wrapping-linux.ll
@@ -28,13 +28,12 @@ define fastcc ptr @wrongUseOfPostDominate(ptr readonly %s, i32 %off, ptr readnon
 ; ENABLE-NEXT:    cmp r0, r2
 ; ENABLE-NEXT:    pophs {r11, pc}
 ; ENABLE-NEXT:  .LBB0_3: @ %while.body.preheader
-; ENABLE-NEXT:    movw r12, :lower16:skip
-; ENABLE-NEXT:    sub r1, r1, #1
-; ENABLE-NEXT:    movt r12, :upper16:skip
+; ENABLE-NEXT:    sub     r1, r1, #1
 ; ENABLE-NEXT:  .LBB0_4: @ %while.body
 ; ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
-; ENABLE-NEXT:    ldrb r3, [r0]
-; ENABLE-NEXT:    ldrb r3, [r12, r3]
+; ENABLE-NEXT:    ldrb    r12, [r0]
+; ENABLE-NEXT:    adr     r3, .LCPI0_0
+; ENABLE-NEXT:    ldrb    r3, [r3, r12]
 ; ENABLE-NEXT:    add r0, r0, r3
 ; ENABLE-NEXT:    sub r3, r1, #1
 ; ENABLE-NEXT:    cmp r3, r1
@@ -104,6 +103,11 @@ define fastcc ptr @wrongUseOfPostDominate(ptr readonly %s, i32 %off, ptr readnon
 ; ENABLE-NEXT:  .LBB0_18:
 ; ENABLE-NEXT:    mov r0, r3
 ; ENABLE-NEXT:    pop {r11, pc}
+; ENABLE-NEXT:    .p2align 2
+; ENABLE-NEXT:  @ %bb.19:
+; ENABLE-NEXT:  .LCPI0_0:
+; ENABLE-NEXT:  skip:
+; ENABLE-NEXT:    .asciz  "\001\001\000"
 ;
 ; DISABLE-LABEL: wrongUseOfPostDominate:
 ; DISABLE:       @ %bb.0: @ %entry
@@ -118,13 +122,12 @@ define fastcc ptr @wrongUseOfPostDominate(ptr readonly %s, i32 %off, ptr readnon
 ; DISABLE-NEXT:    cmp r0, r2
 ; DISABLE-NEXT:    pophs {r11, pc}
 ; DISABLE-NEXT:  .LBB0_3: @ %while.body.preheader
-; DISABLE-NEXT:    movw r12, :lower16:skip
 ; DISABLE-NEXT:    sub r1, r1, #1
-; DISABLE-NEXT:    movt r12, :upper16:skip
 ; DISABLE-NEXT:  .LBB0_4: @ %while.body
 ; DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
-; DISABLE-NEXT:    ldrb r3, [r0]
-; DISABLE-NEXT:    ldrb r3, [r12, r3]
+; DISABLE-NEXT:    ldrb r12, [r0]
+; DISABLE-NEXT:    adr r3, .LCPI0_0
+; DISABLE-NEXT:    ldrb r3, [r3, r12]
 ; DISABLE-NEXT:    add r0, r0, r3
 ; DISABLE-NEXT:    sub r3, r1, #1
 ; DISABLE-NEXT:    cmp r3, r1
@@ -194,6 +197,11 @@ define fastcc ptr @wrongUseOfPostDominate(ptr readonly %s, i32 %off, ptr readnon
 ; DISABLE-NEXT:  .LBB0_18:
 ; DISABLE-NEXT:    mov r0, r3
 ; DISABLE-NEXT:    pop {r11, pc}
+; DISABLE-NEXT:    .p2align 2
+; DISABLE-NEXT:  @ %bb.19:
+; DISABLE-NEXT:  .LCPI0_0:
+; DISABLE-NEXT:  skip:
+; DISABLE-NEXT:    .asciz  "\001\001\000"
 entry:
   %cmp = icmp sgt i32 %off, -1
   br i1 %cmp, label %while.cond.preheader, label %while.cond2.outer
diff --git a/llvm/test/CodeGen/ARM/constantpool-promote.ll b/llvm/test/CodeGen/ARM/constantpool-promote.ll
index c383b391db8332..a19c90454380f4 100644
--- a/llvm/test/CodeGen/ARM/constantpool-promote.ll
+++ b/llvm/test/CodeGen/ARM/constantpool-promote.ll
@@ -54,11 +54,9 @@ define void @test3() #0 {
   ret void
 }
 
-
+; Not promoted due to multiple uses until issue #32127 is fixed.
 ; CHECK-LABEL: @test4
-; CHECK: adr r{{.*}}, [[x:.*]]
-; CHECK: [[x]]:
-; CHECK: .asciz "this string is used twice\000\000"
+; CHECK-NOT: adr
 define void @test4() #0 {
   tail call void @a(ptr @.str3) #2
   tail call void @a(ptr @.str3) #2
diff --git a/llvm/test/CodeGen/ARM/memcpy-inline.ll b/llvm/test/CodeGen/ARM/memcpy-inline.ll
index 596a58afe46e5b..6a02b659179f94 100644
--- a/llvm/test/CodeGen/ARM/memcpy-inline.ll
+++ b/llvm/test/CodeGen/ARM/memcpy-inline.ll
@@ -77,14 +77,15 @@ define void @t1(ptr nocapture %C) nounwind {
 ; CHECK-T1:       @ %bb.0: @ %entry
 ; CHECK-T1-NEXT:    .save {r7, lr}
 ; CHECK-T1-NEXT:    push {r7, lr}
-; CHECK-T1-NEXT:    ldr r1, .LCPI1_0
+; CHECK-T1-NEXT:    adr r1, .LCPI1_0
 ; CHECK-T1-NEXT:    movs r2, #31
 ; CHECK-T1-NEXT:    bl __aeabi_memcpy
 ; CHECK-T1-NEXT:    pop {r7, pc}
 ; CHECK-T1-NEXT:    .p2align 2
 ; CHECK-T1-NEXT:  @ %bb.1:
 ; CHECK-T1-NEXT:  .LCPI1_0:
-; CHECK-T1-NEXT:    .long .L.str1
+; CHECK-T1-NEXT:  .L.str1:
+; CHECK-T1-NEXT:    .asciz  "DHRYSTONE PROGRAM, SOME STRING\000"
 entry:
   tail call void @llvm.memcpy.p0.p0.i64(ptr %C, ptr @.str1, i64 31, i1 false)
   ret void
@@ -110,14 +111,15 @@ define void @t2(ptr nocapture %C) nounwind {
 ; CHECK-T1:       @ %bb.0: @ %entry
 ; CHECK-T1-NEXT:    .save {r7, lr}
 ; CHECK-T1-NEXT:    push {r7, lr}
-; CHECK-T1-NEXT:    ldr r1, .LCPI2_0
+; CHECK-T1-NEXT:    adr r1, .LCPI2_0
 ; CHECK-T1-NEXT:    movs r2, #36
 ; CHECK-T1-NEXT:    bl __aeabi_memcpy
 ; CHECK-T1-NEXT:    pop {r7, pc}
 ; CHECK-T1-NEXT:    .p2align 2
 ; CHECK-T1-NEXT:  @ %bb.1:
 ; CHECK-T1-NEXT:  .LCPI2_0:
-; CHECK-T1-NEXT:    .long .L.str2
+; CHECK-T1-NEXT:  .L.str2:
+; CHECK-T1-NEXT:    .asciz  "DHRYSTONE PROGRAM, SOME STRING BLAH"
 entry:
   tail call void @llvm.memcpy.p0.p0.i64(ptr %C, ptr @.str2, i64 36, i1 false)
   ret void
@@ -140,14 +142,15 @@ define void @t3(ptr nocapture %C) nounwind {
 ; CHECK-T1:       @ %bb.0: @ %entry
 ; CHECK-T1-NEXT:    .save {r7, lr}
 ; CHECK-T1-NEXT:    push {r7, lr}
-; CHECK-T1-NEXT:    ldr r1, .LCPI3_0
+; CHECK-T1-NEXT:    adr r1, .LCPI3_0
 ; CHECK-T1-NEXT:    movs r2, #24
 ; CHECK-T1-NEXT:    bl __aeabi_memcpy
 ; CHECK-T1-NEXT:    pop {r7, pc}
 ; CHECK-T1-NEXT:    .p2align 2
 ; CHECK-T1-NEXT:  @ %bb.1:
 ; CHECK-T1-NEXT:  .LCPI3_0:
-; CHECK-T1-NEXT:    .long .L.str3
+; CHECK-T1-NEXT:  .L.str3:
+; CHECK-T1-NEXT:    .asciz  "DHRYSTONE PROGRAM, SOME"
 entry:
   tail call void @llvm.memcpy.p0.p0.i64(ptr %C, ptr @.str3, i64 24, i1 false)
   ret void
@@ -170,14 +173,16 @@ define void @t4(ptr nocapture %C) nounwind {
 ; CHECK-T1:       @ %bb.0: @ %entry
 ; CHECK-T1-NEXT:    .save {r7, lr}
 ; CHECK-T1-NEXT:    push {r7, lr}
-; CHECK-T1-NEXT:    ldr r1, .LCPI4_0
+; CHECK-T1-NEXT:    adr r1, .LCPI4_0
 ; CHECK-T1-NEXT:    movs r2, #18
 ; CHECK-T1-NEXT:    bl __aeabi_memcpy
 ; CHECK-T1-NEXT:    pop {r7, pc}
 ; CHECK-T1-NEXT:    .p2align 2
 ; CHECK-T1-NEXT:  @ %bb.1:
 ; CHECK-T1-NEXT:  .LCPI4_0:
-; CHECK-T1-NEXT:    .long .L.str4
+; CHECK-T1-NEXT:  .L.str4:
+; CHECK-T1-NEXT:    .asciz  "DHRYSTONE PROGR  \000\000"
+
 entry:
   tail call void @llvm.memcpy.p0.p0.i64(ptr %C, ptr @.str4, i64 18, i1 false)
   ret void
@@ -198,14 +203,15 @@ define void @t5(ptr nocapture %C) nounwind {
 ; CHECK-T1:       @ %bb.0: @ %entry
 ; CHECK-T1-NEXT:    .save {r7, lr}
 ; CHECK-T1-NEXT:    push {r7, lr}
-; CHECK-T1-NEXT:    ldr r1, .LCPI5_0
+; CHECK-T1-NEXT:    adr r1, .LCPI5_0
 ; CHECK-T1-NEXT:    movs r2, #7
 ; CHECK-T1-NEXT:    bl __aeabi_memcpy
 ; CHECK-T1-NEXT:    pop {r7, pc}
 ; CHECK-T1-NEXT:    .p2align 2
 ; CHECK-T1-NEXT:  @ %bb.1:
 ; CHECK-T1-NEXT:  .LCPI5_0:
-; CHECK-T1-NEXT:    .long .L.str5
+; CHECK-T1-NEXT:  .L.str5:
+; CHECK-T1-NEXT:    .asciz  "DHRYST\000"
 entry:
   tail call void @llvm.memcpy.p0.p0.i64(ptr %C, ptr @.str5, i64 7, i1 false)
   ret void
diff --git a/llvm/test/CodeGen/Thumb2/bti-indirect-branches.ll b/llvm/test/CodeGen/Thumb2/bti-indirect-branches.ll
index c6ffb92d60d8d0..edce7a53cee4e2 100644
--- a/llvm/test/CodeGen/Thumb2/bti-indirect-branches.ll
+++ b/llvm/test/CodeGen/Thumb2/bti-indirect-branches.ll
@@ -61,8 +61,7 @@ define internal i32 @computed_goto(i32 %x) "branch-target-enforcement" {
 ; CHECK-LABEL: computed_goto:
 ; CHECK:       @ %bb.0: @ %entry
 ; CHECK-NEXT:    bti
-; CHECK-NEXT:    movw r1, :lower16:.Lcomputed_goto_cases
-; CHECK-NEXT:    movt r1, :upper16:.Lcomputed_goto_cases
+; CHECK-NEXT:    adr     r1, .LCPI1_0
 ; CHECK-NEXT:    ldr.w r0, [r1, r0, lsl #2]
 ; CHECK-NEXT:    mov pc, r0
 ; CHECK-NEXT:  .Ltmp3: @ Block address taken
@@ -75,6 +74,12 @@ define internal i32 @computed_goto(i32 %x) "branch-target-enforcement" {
 ; CHECK-NEXT:    bti
 ; CHECK-NEXT:    movs r0, #1
 ; CHECK-NEXT:    bx lr
+; CHECK-NEXT:    .p2align        2
+; CHECK-NEXT:  @ %bb.3:
+; CHECK-NEXT:  .LCPI1_0:
+; CHECK-NEXT:  .Lcomputed_goto_cases:
+; CHECK-NEXT:    .long   .Ltmp3
+; CHECK-NEXT:    .long   .Ltmp4
 entry:
   %arrayidx = getelementptr inbounds [2 x ptr], ptr @computed_goto_cases, i32 0, i32 %x
   %0 = load ptr, ptr %arrayidx, align 4



More information about the llvm-commits mailing list