[llvm] 4b150e5 - [GlobalOpt] Use getGetElementPtr() overload accepting a DataLayout (#225789)

via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 23 09:47:01 PDT 2026


Author: Nikita Popov
Date: 2026-09-23T16:46:54Z
New Revision: 4b150e53377a931ab02a2c6b225ccdd75e0d8284

URL: https://github.com/llvm/llvm-project/commit/4b150e53377a931ab02a2c6b225ccdd75e0d8284
DIFF: https://github.com/llvm/llvm-project/commit/4b150e53377a931ab02a2c6b225ccdd75e0d8284.diff

LOG: [GlobalOpt] Use getGetElementPtr() overload accepting a DataLayout (#225789)

To produce the GEP in canonical ptradd form. Unlike other uses,
this one has to take potential failure to create the constant
expression into account.

It also seems like the GEP path was entirely untested, so I added
some basic test coverage for it.

Added: 
    

Modified: 
    llvm/lib/Transforms/IPO/GlobalOpt.cpp
    llvm/test/Transforms/GlobalOpt/storepointer.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
index b16c58ad8f8c8..36563e25cc7f7 100644
--- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
@@ -814,10 +814,11 @@ static bool OptimizeAwayTrappingUsesOfValue(Instruction *V, Constant *NewV) {
           Idxs.push_back(C);
         else
           break;
-      if (Idxs.size() == GEPI->getNumOperands()-1)
-        Changed |= OptimizeAwayTrappingUsesOfValue(
-            GEPI, ConstantExpr::getGetElementPtr(GEPI->getSourceElementType(),
-                                                 NewV, Idxs));
+      if (Idxs.size() == GEPI->getNumOperands() - 1) {
+        if (Constant *NewGEP = ConstantExpr::getGetElementPtr(
+                V->getDataLayout(), GEPI->getSourceElementType(), NewV, Idxs))
+          Changed |= OptimizeAwayTrappingUsesOfValue(GEPI, NewGEP);
+      }
       if (GEPI->use_empty()) {
         Changed = true;
         GEPI->eraseFromParent();

diff  --git a/llvm/test/Transforms/GlobalOpt/storepointer.ll b/llvm/test/Transforms/GlobalOpt/storepointer.ll
index 9a88ee0a21763..502803682cced 100644
--- a/llvm/test/Transforms/GlobalOpt/storepointer.ll
+++ b/llvm/test/Transforms/GlobalOpt/storepointer.ll
@@ -1,19 +1,89 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
 ; RUN: opt < %s -passes=globalopt -S | FileCheck %s
-; CHECK-NOT: global
 
- at G = internal global ptr null              ; <ptr> [#uses=2]
+ at G = internal global ptr null
+ at G2 = internal global ptr null
+ at glob = global { i32, i32 } zeroinitializer
 
 define internal void @Actual() {
-        ret void
+; CHECK-LABEL: define internal fastcc void @Actual() unnamed_addr {
+; CHECK-NEXT:    ret void
+;
+  ret void
 }
 
 define void @init() {
-        store ptr @Actual, ptr @G
-        ret void
+; CHECK-LABEL: define void @init() local_unnamed_addr {
+; CHECK-NEXT:    store ptr @glob, ptr @G2, align 8
+; CHECK-NEXT:    ret void
+;
+  store ptr @Actual, ptr @G
+  store ptr @glob, ptr @G2
+  ret void
 }
 
-define void @doit() {
-        %FP = load ptr, ptr @G         ; <ptr> [#uses=1]
-        call void %FP( )
-        ret void
+define void @call() {
+; CHECK-LABEL: define void @call() local_unnamed_addr {
+; CHECK-NEXT:    call fastcc void @Actual()
+; CHECK-NEXT:    ret void
+;
+  %FP = load ptr, ptr @G
+  call void %FP()
+  ret void
+}
+
+define i32 @load() {
+; CHECK-LABEL: define i32 @load() local_unnamed_addr {
+; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr @glob, align 4
+; CHECK-NEXT:    [[B:%.*]] = load i32, ptr getelementptr (i8, ptr @glob, i64 4), align 4
+; CHECK-NEXT:    [[RES1:%.*]] = add i32 [[RES]], [[B]]
+; CHECK-NEXT:    ret i32 [[RES1]]
+;
+  %g = load ptr, ptr @G2
+  %a = load i32, ptr %g
+  %gep = getelementptr i8, ptr %g, i64 4
+  %b = load i32, ptr %gep
+  %res = add i32 %a, %b
+  ret i32 %res
+}
+
+define void @store() {
+; CHECK-LABEL: define void @store() local_unnamed_addr {
+; CHECK-NEXT:    store i32 1, ptr @glob, align 4
+; CHECK-NEXT:    store i32 2, ptr getelementptr (i8, ptr @glob, i64 4), align 4
+; CHECK-NEXT:    ret void
+;
+  %g = load ptr, ptr @G2
+  store i32 1, ptr %g
+  %gep = getelementptr i8, ptr %g, i64 4
+  store i32 2, ptr %gep
+  ret void
+}
+
+define void @gep_variable(i64 %offset) {
+; CHECK-LABEL: define void @gep_variable(
+; CHECK-SAME: i64 [[OFFSET:%.*]]) local_unnamed_addr {
+; CHECK-NEXT:    [[G:%.*]] = load ptr, ptr @G2, align 8
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[G]], i64 [[OFFSET]]
+; CHECK-NEXT:    store i32 0, ptr [[GEP]], align 4
+; CHECK-NEXT:    ret void
+;
+  %g = load ptr, ptr @G2
+  %gep = getelementptr i8, ptr %g, i64 %offset
+  store i32 0, ptr %gep
+  ret void
+}
+
+define void @gep_constexpr_complex(i64 %offset) {
+; CHECK-LABEL: define void @gep_constexpr_complex(
+; CHECK-SAME: i64 [[OFFSET:%.*]]) local_unnamed_addr {
+; CHECK-NEXT:    [[G:%.*]] = load ptr, ptr @G2, align 8
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[G]], i64 ptrtoint (ptr @glob to i64)
+; CHECK-NEXT:    store i32 0, ptr [[GEP]], align 4
+; CHECK-NEXT:    ret void
+;
+  %g = load ptr, ptr @G2
+  %gep = getelementptr i32, ptr %g, i64 ptrtoint (ptr @glob to i64)
+  store i32 0, ptr %gep
+  ret void
 }


        


More information about the llvm-commits mailing list