Skip to content

[ConstantFolding] Canonicalize constexpr GEPs to i8 #89872

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
May 20, 2024

Conversation

nikic
Copy link
Contributor

@nikic nikic commented Apr 24, 2024

This patch canonicalizes constant expression GEPs to use i8 source element type, aka ptradd. This is the ConstantFolding equivalent of the InstCombine canonicalization introduced in #68882.

I believe all our optimizations working on constant expression GEPs (like GlobalOpt etc) have already been switched to work on offsets, so I don't expect any significant fallout from this change.

This is part of:
https://discourse.llvm.org/t/rfc-replacing-getelementptr-with-ptradd/68699

@llvmbot
Copy link
Member

llvmbot commented Apr 24, 2024

@llvm/pr-subscribers-pgo
@llvm/pr-subscribers-llvm-analysis
@llvm/pr-subscribers-llvm-transforms
@llvm/pr-subscribers-clang
@llvm/pr-subscribers-backend-systemz
@llvm/pr-subscribers-backend-risc-v

@llvm/pr-subscribers-function-specialization

Author: Nikita Popov (nikic)

Changes

This patch canonicalizes constant expression GEPs to use i8 source element type, aka ptradd. This is the ConstantFolding equivalent of the InstCombine canonicalization introduced in #68882.

I believe all our optimizations working on constant expression GEPs (like GlobalOpt etc) have already been switched to work on offsets, so I don't expect any significant fallout from this change.

This is part of:
https://discourse.llvm.org/t/rfc-replacing-getelementptr-with-ptradd/68699


Patch is 258.02 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/89872.diff

96 Files Affected:

  • (modified) clang/test/CodeGen/RISCV/riscv-inline-asm.c (+3-3)
  • (modified) clang/test/CodeGen/attr-counted-by.c (+29-29)
  • (modified) clang/test/CodeGenCXX/atomicinit.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/auto-var-init.cpp (+2-2)
  • (modified) clang/test/Profile/c-unreachable-after-switch.c (+2-2)
  • (modified) llvm/lib/Analysis/ConstantFolding.cpp (+10-36)
  • (modified) llvm/test/Other/constant-fold-gep.ll (+7-7)
  • (modified) llvm/test/Other/optimize-inrange-gep.ll (+1-1)
  • (modified) llvm/test/Transforms/FunctionSpecialization/function-specialization-constant-expression.ll (+3-3)
  • (modified) llvm/test/Transforms/GVN/PRE/load-pre-licm.ll (+1-1)
  • (modified) llvm/test/Transforms/GVN/PRE/phi-translate-2.ll (+2-2)
  • (modified) llvm/test/Transforms/IndVarSimplify/D108043.ll (+1-1)
  • (modified) llvm/test/Transforms/IndVarSimplify/eliminate-exit-no-dl.ll (+1-1)
  • (modified) llvm/test/Transforms/IndVarSimplify/floating-point-small-iv.ll (+2-2)
  • (modified) llvm/test/Transforms/IndVarSimplify/lftr-dead-ivs.ll (+3-3)
  • (modified) llvm/test/Transforms/IndVarSimplify/lftr.ll (+1-1)
  • (modified) llvm/test/Transforms/InstCombine/addrspacecast.ll (+1-1)
  • (modified) llvm/test/Transforms/InstCombine/align-addr.ll (+1-1)
  • (modified) llvm/test/Transforms/InstCombine/binop-select-cast-of-select-cond.ll (+1-1)
  • (modified) llvm/test/Transforms/InstCombine/constant-fold-address-space-pointer.ll (+1-1)
  • (modified) llvm/test/Transforms/InstCombine/constant-fold-gep.ll (+20-20)
  • (modified) llvm/test/Transforms/InstCombine/fmul.ll (+1-1)
  • (modified) llvm/test/Transforms/InstCombine/force-opaque-ptr.ll (+2-2)
  • (modified) llvm/test/Transforms/InstCombine/fortify-folding.ll (+2-2)
  • (modified) llvm/test/Transforms/InstCombine/gep-custom-dl.ll (+3-3)
  • (modified) llvm/test/Transforms/InstCombine/getelementptr.ll (+14-14)
  • (modified) llvm/test/Transforms/InstCombine/hoist-xor-by-constant-from-xor-by-value.ll (+1-1)
  • (modified) llvm/test/Transforms/InstCombine/loadstore-alignment.ll (+2-2)
  • (modified) llvm/test/Transforms/InstCombine/memchr-2.ll (+5-5)
  • (modified) llvm/test/Transforms/InstCombine/memchr-4.ll (+1-1)
  • (modified) llvm/test/Transforms/InstCombine/memchr-6.ll (+2-2)
  • (modified) llvm/test/Transforms/InstCombine/memchr-7.ll (+1-1)
  • (modified) llvm/test/Transforms/InstCombine/memchr-8.ll (+3-3)
  • (modified) llvm/test/Transforms/InstCombine/memchr-9.ll (+18-18)
  • (modified) llvm/test/Transforms/InstCombine/memchr.ll (+6-6)
  • (modified) llvm/test/Transforms/InstCombine/memcmp-8.ll (+1-1)
  • (modified) llvm/test/Transforms/InstCombine/memcpy-from-global.ll (+4-4)
  • (modified) llvm/test/Transforms/InstCombine/memrchr-3.ll (+10-10)
  • (modified) llvm/test/Transforms/InstCombine/memrchr-4.ll (+2-2)
  • (modified) llvm/test/Transforms/InstCombine/merging-multiple-stores-into-successor.ll (+3-3)
  • (modified) llvm/test/Transforms/InstCombine/objsize.ll (+2-2)
  • (modified) llvm/test/Transforms/InstCombine/pr25342.ll (+5-5)
  • (modified) llvm/test/Transforms/InstCombine/pr33453.ll (+1-1)
  • (modified) llvm/test/Transforms/InstCombine/pr38984-inseltpoison.ll (+1-1)
  • (modified) llvm/test/Transforms/InstCombine/pr38984.ll (+1-1)
  • (modified) llvm/test/Transforms/InstCombine/pr83947.ll (+2-2)
  • (modified) llvm/test/Transforms/InstCombine/ptr-replace-alloca.ll (+4-4)
  • (modified) llvm/test/Transforms/InstCombine/rem.ll (+2-2)
  • (modified) llvm/test/Transforms/InstCombine/select-and-or.ll (+2-2)
  • (modified) llvm/test/Transforms/InstCombine/simplify-libcalls-i16.ll (+5-5)
  • (modified) llvm/test/Transforms/InstCombine/simplify-libcalls.ll (+5-5)
  • (modified) llvm/test/Transforms/InstCombine/snprintf-2.ll (+24-24)
  • (modified) llvm/test/Transforms/InstCombine/snprintf-3.ll (+24-24)
  • (modified) llvm/test/Transforms/InstCombine/snprintf-4.ll (+15-15)
  • (modified) llvm/test/Transforms/InstCombine/stpcpy-1.ll (+2-2)
  • (modified) llvm/test/Transforms/InstCombine/stpcpy_chk-1.ll (+5-5)
  • (modified) llvm/test/Transforms/InstCombine/stpncpy-1.ll (+19-16)
  • (modified) llvm/test/Transforms/InstCombine/str-int-2.ll (+1-1)
  • (modified) llvm/test/Transforms/InstCombine/str-int-3.ll (+2-2)
  • (modified) llvm/test/Transforms/InstCombine/str-int-4.ll (+20-20)
  • (modified) llvm/test/Transforms/InstCombine/str-int-5.ll (+25-25)
  • (modified) llvm/test/Transforms/InstCombine/str-int.ll (+1-1)
  • (modified) llvm/test/Transforms/InstCombine/strcall-bad-sig.ll (+5-5)
  • (modified) llvm/test/Transforms/InstCombine/strcall-no-nul.ll (+10-10)
  • (modified) llvm/test/Transforms/InstCombine/strchr-1.ll (+3-3)
  • (modified) llvm/test/Transforms/InstCombine/strchr-3.ll (+6-6)
  • (modified) llvm/test/Transforms/InstCombine/strcmp-4.ll (+2-2)
  • (modified) llvm/test/Transforms/InstCombine/strlcpy-1.ll (+2-2)
  • (modified) llvm/test/Transforms/InstCombine/strlen-1.ll (+1-1)
  • (modified) llvm/test/Transforms/InstCombine/strlen-6.ll (+9-9)
  • (modified) llvm/test/Transforms/InstCombine/strpbrk-1.ll (+1-1)
  • (modified) llvm/test/Transforms/InstCombine/strrchr-1.ll (+3-3)
  • (modified) llvm/test/Transforms/InstCombine/strrchr-3.ll (+4-4)
  • (modified) llvm/test/Transforms/InstCombine/strstr-1.ll (+1-1)
  • (modified) llvm/test/Transforms/InstCombine/vec_demanded_elts-inseltpoison.ll (+1-1)
  • (modified) llvm/test/Transforms/InstCombine/vec_demanded_elts.ll (+1-1)
  • (modified) llvm/test/Transforms/InstCombine/wcslen-1.ll (+2-2)
  • (modified) llvm/test/Transforms/InstSimplify/ConstProp/gep-alias.ll (+1-1)
  • (modified) llvm/test/Transforms/InstSimplify/ConstProp/gep-constanfolding-error.ll (+1-2)
  • (modified) llvm/test/Transforms/InstSimplify/ConstProp/gep.ll (+3-3)
  • (modified) llvm/test/Transforms/InstSimplify/ConstProp/icmp-global.ll (+5-5)
  • (modified) llvm/test/Transforms/InstSimplify/compare.ll (+1-1)
  • (modified) llvm/test/Transforms/InstSimplify/past-the-end.ll (+2-2)
  • (modified) llvm/test/Transforms/LoopStrengthReduce/2011-12-19-PostincQuadratic.ll (+1-1)
  • (modified) llvm/test/Transforms/LoopStrengthReduce/X86/2012-01-13-phielim.ll (+10-10)
  • (modified) llvm/test/Transforms/LoopVectorize/X86/pr42674.ll (+1-1)
  • (modified) llvm/test/Transforms/LoopVectorize/pr47343-expander-lcssa-after-cfg-update.ll (+2-2)
  • (modified) llvm/test/Transforms/LoopVersioning/add-phi-update-users.ll (+3-3)
  • (modified) llvm/test/Transforms/LoopVersioning/bound-check-partially-known.ll (+5-5)
  • (modified) llvm/test/Transforms/NewGVN/loadforward.ll (+1-1)
  • (modified) llvm/test/Transforms/PhaseOrdering/SystemZ/sub-xor.ll (+24-24)
  • (modified) llvm/test/Transforms/PhaseOrdering/X86/excessive-unrolling.ll (+90-90)
  • (modified) llvm/test/Transforms/SCCP/2009-09-24-byval-ptr.ll (+1-1)
  • (modified) llvm/test/Transforms/SCCP/apint-bigint2.ll (+3-3)
  • (modified) llvm/test/Transforms/SLPVectorizer/AArch64/gather-cost.ll (+4-4)
  • (modified) llvm/test/Transforms/SLPVectorizer/X86/pr47623.ll (+14-14)
diff --git a/clang/test/CodeGen/RISCV/riscv-inline-asm.c b/clang/test/CodeGen/RISCV/riscv-inline-asm.c
index 3565705dea7130..ed97add95e7116 100644
--- a/clang/test/CodeGen/RISCV/riscv-inline-asm.c
+++ b/clang/test/CodeGen/RISCV/riscv-inline-asm.c
@@ -49,9 +49,9 @@ extern int var, arr[2][2];
 struct Pair { int a, b; } pair;
 
 // CHECK-LABEL: test_s(
-// CHECK:         call void asm sideeffect "// $0 $1 $2", "s,s,s"(ptr nonnull @var, ptr nonnull getelementptr inbounds ([2 x [2 x i32]], ptr @arr, {{.*}}), ptr nonnull @test_s)
-// CHECK:         call void asm sideeffect "// $0", "s"(ptr nonnull getelementptr inbounds (%struct.Pair, ptr @pair, {{.*}}))
-// CHECK:         call void asm sideeffect "// $0 $1 $2", "S,S,S"(ptr nonnull @var, ptr nonnull getelementptr inbounds ([2 x [2 x i32]], ptr @arr, {{.*}}), ptr nonnull @test_s)
+// CHECK:         call void asm sideeffect "// $0 $1 $2", "s,s,s"(ptr nonnull @var, ptr nonnull getelementptr inbounds (i8, ptr @arr, {{.*}}), ptr nonnull @test_s)
+// CHECK:         call void asm sideeffect "// $0", "s"(ptr nonnull getelementptr inbounds (i8, ptr @pair, {{.*}}))
+// CHECK:         call void asm sideeffect "// $0 $1 $2", "S,S,S"(ptr nonnull @var, ptr nonnull getelementptr inbounds (i8, ptr @arr, {{.*}}), ptr nonnull @test_s)
 void test_s(void) {
   asm("// %0 %1 %2" :: "s"(&var), "s"(&arr[1][1]), "s"(test_s));
   asm("// %0" :: "s"(&pair.b));
diff --git a/clang/test/CodeGen/attr-counted-by.c b/clang/test/CodeGen/attr-counted-by.c
index 1fb39f9a346667..6fc563aba2ae22 100644
--- a/clang/test/CodeGen/attr-counted-by.c
+++ b/clang/test/CodeGen/attr-counted-by.c
@@ -66,7 +66,7 @@ struct anon_struct {
 // SANITIZE-WITH-ATTR-NEXT:    [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    br i1 [[TMP1]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       handler.out_of_bounds:
-// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10:[0-9]+]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10:[0-9]+]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    unreachable, !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       cont3:
 // SANITIZE-WITH-ATTR-NEXT:    [[ARRAY:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12
@@ -114,7 +114,7 @@ void test1(struct annotated *p, int index, int val) {
 // SANITIZE-WITH-ATTR-NEXT:    [[TMP1:%.*]] = icmp ugt i64 [[TMP0]], [[INDEX]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    br i1 [[TMP1]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       handler.out_of_bounds:
-// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 [[INDEX]]) #[[ATTR10]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB3:[0-9]+]], i64 [[INDEX]]) #[[ATTR10]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    unreachable, !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       cont3:
 // SANITIZE-WITH-ATTR-NEXT:    [[ARRAY:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12
@@ -203,7 +203,7 @@ size_t test2_bdos(struct annotated *p) {
 // SANITIZE-WITH-ATTR-NEXT:    [[TMP1:%.*]] = icmp ugt i64 [[TMP0]], [[INDEX]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    br i1 [[TMP1]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       handler.out_of_bounds:
-// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[INDEX]]) #[[ATTR10]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 [[INDEX]]) #[[ATTR10]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    unreachable, !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       cont3:
 // SANITIZE-WITH-ATTR-NEXT:    [[ARRAY:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12
@@ -308,7 +308,7 @@ size_t test3_bdos(struct annotated *p) {
 // SANITIZE-WITH-ATTR-NEXT:    [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    br i1 [[TMP1]], label [[CONT4:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       handler.out_of_bounds:
-// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    unreachable, !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       cont4:
 // SANITIZE-WITH-ATTR-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD]], 2
@@ -325,7 +325,7 @@ size_t test3_bdos(struct annotated *p) {
 // SANITIZE-WITH-ATTR-NEXT:    [[TMP7:%.*]] = icmp ult i64 [[IDXPROM13]], [[TMP6]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    br i1 [[TMP7]], label [[CONT20:%.*]], label [[HANDLER_OUT_OF_BOUNDS16:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       handler.out_of_bounds16:
-// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB7:[0-9]+]], i64 [[IDXPROM13]]) #[[ATTR10]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[IDXPROM13]]) #[[ATTR10]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    unreachable, !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       cont20:
 // SANITIZE-WITH-ATTR-NEXT:    [[TMP8:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD7]], 3
@@ -342,7 +342,7 @@ size_t test3_bdos(struct annotated *p) {
 // SANITIZE-WITH-ATTR-NEXT:    [[TMP13:%.*]] = icmp ult i64 [[IDXPROM30]], [[TMP12]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    br i1 [[TMP13]], label [[CONT37:%.*]], label [[HANDLER_OUT_OF_BOUNDS33:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       handler.out_of_bounds33:
-// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB8:[0-9]+]], i64 [[IDXPROM30]]) #[[ATTR10]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB7:[0-9]+]], i64 [[IDXPROM30]]) #[[ATTR10]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    unreachable, !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       cont37:
 // SANITIZE-WITH-ATTR-NEXT:    [[ARRAYIDX35:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM30]]
@@ -494,7 +494,7 @@ size_t test4_bdos(struct annotated *p, int index) {
 // SANITIZE-WITH-ATTR-NEXT:    [[TMP0:%.*]] = icmp ugt i64 [[DOT_COUNTED_BY_LOAD]], [[IDXPROM]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    br i1 [[TMP0]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       handler.out_of_bounds:
-// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB8:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    unreachable, !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       cont3:
 // SANITIZE-WITH-ATTR-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 16
@@ -590,7 +590,7 @@ size_t test5_bdos(struct anon_struct *p) {
 // SANITIZE-WITH-ATTR-NEXT:    [[TMP0:%.*]] = icmp ugt i64 [[DOT_COUNTED_BY_LOAD]], [[IDXPROM]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    br i1 [[TMP0]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       handler.out_of_bounds:
-// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB10:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    unreachable, !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       cont3:
 // SANITIZE-WITH-ATTR-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 16
@@ -683,7 +683,7 @@ size_t test6_bdos(struct anon_struct *p) {
 // SANITIZE-WITH-ATTR-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP1]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    br i1 [[TMP2]], label [[CONT7:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       handler.out_of_bounds:
-// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB12:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB11:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    unreachable, !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       cont7:
 // SANITIZE-WITH-ATTR-NEXT:    [[INTS:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 9
@@ -756,7 +756,7 @@ size_t test7_bdos(struct union_of_fams *p) {
 // SANITIZE-WITH-ATTR-NEXT:    [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    br i1 [[TMP1]], label [[CONT9:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       handler.out_of_bounds:
-// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB13:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB12:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    unreachable, !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       cont9:
 // SANITIZE-WITH-ATTR-NEXT:    [[INTS:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 9
@@ -1095,10 +1095,10 @@ int test12_a, test12_b;
 // SANITIZE-WITH-ATTR-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[DOTCOUNTED_BY_LOAD]], 0
 // SANITIZE-WITH-ATTR-NEXT:    br i1 [[DOTNOT]], label [[HANDLER_OUT_OF_BOUNDS4:%.*]], label [[HANDLER_TYPE_MISMATCH6:%.*]], !prof [[PROF10:![0-9]+]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       handler.out_of_bounds4:
-// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB19:[0-9]+]], i64 0) #[[ATTR10]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB20:[0-9]+]], i64 0) #[[ATTR10]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    unreachable, !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       handler.type_mismatch6:
-// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB20:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds ([[STRUCT_ANON_5:%.*]], ptr @test12_foo, i64 1, i32 0, i32 0, i32 0) to i64)) #[[ATTR10]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB21:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds (i8, ptr @test12_foo, i64 4) to i64)) #[[ATTR10]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    unreachable, !nosanitize [[META2]]
 //
 // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i32 @test12(
@@ -1111,7 +1111,7 @@ int test12_a, test12_b;
 // NO-SANITIZE-WITH-ATTR-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [6 x i32], ptr [[BAZ]], i64 0, i64 [[IDXPROM]]
 // NO-SANITIZE-WITH-ATTR-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]]
 // NO-SANITIZE-WITH-ATTR-NEXT:    store i32 [[TMP0]], ptr @test12_b, align 4, !tbaa [[TBAA2]]
-// NO-SANITIZE-WITH-ATTR-NEXT:    [[TMP1:%.*]] = load i32, ptr getelementptr inbounds ([[STRUCT_ANON_5:%.*]], ptr @test12_foo, i64 1, i32 0, i32 0, i32 0), align 4, !tbaa [[TBAA2]]
+// NO-SANITIZE-WITH-ATTR-NEXT:    [[TMP1:%.*]] = load i32, ptr getelementptr inbounds (i8, ptr @test12_foo, i64 4), align 4, !tbaa [[TBAA2]]
 // NO-SANITIZE-WITH-ATTR-NEXT:    store i32 [[TMP1]], ptr @test12_a, align 4, !tbaa [[TBAA2]]
 // NO-SANITIZE-WITH-ATTR-NEXT:    br label [[FOR_COND:%.*]]
 // NO-SANITIZE-WITH-ATTR:       for.cond:
@@ -1140,7 +1140,7 @@ int test12_a, test12_b;
 // SANITIZE-WITHOUT-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 0) #[[ATTR8]], !nosanitize [[META9]]
 // SANITIZE-WITHOUT-ATTR-NEXT:    unreachable, !nosanitize [[META9]]
 // SANITIZE-WITHOUT-ATTR:       handler.type_mismatch6:
-// SANITIZE-WITHOUT-ATTR-NEXT:    tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds ([[STRUCT_ANON_5:%.*]], ptr @test12_foo, i64 1, i32 0, i32 0, i32 0) to i64)) #[[ATTR8]], !nosanitize [[META9]]
+// SANITIZE-WITHOUT-ATTR-NEXT:    tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds (i8, ptr @test12_foo, i64 4) to i64)) #[[ATTR8]], !nosanitize [[META9]]
 // SANITIZE-WITHOUT-ATTR-NEXT:    unreachable, !nosanitize [[META9]]
 //
 // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i32 @test12(
@@ -1153,7 +1153,7 @@ int test12_a, test12_b;
 // NO-SANITIZE-WITHOUT-ATTR-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [6 x i32], ptr [[BAZ]], i64 0, i64 [[IDXPROM]]
 // NO-SANITIZE-WITHOUT-ATTR-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]]
 // NO-SANITIZE-WITHOUT-ATTR-NEXT:    store i32 [[TMP0]], ptr @test12_b, align 4, !tbaa [[TBAA2]]
-// NO-SANITIZE-WITHOUT-ATTR-NEXT:    [[TMP1:%.*]] = load i32, ptr getelementptr inbounds ([[STRUCT_ANON_5:%.*]], ptr @test12_foo, i64 1, i32 0, i32 0, i32 0), align 4, !tbaa [[TBAA2]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT:    [[TMP1:%.*]] = load i32, ptr getelementptr inbounds (i8, ptr @test12_foo, i64 4), align 4, !tbaa [[TBAA2]]
 // NO-SANITIZE-WITHOUT-ATTR-NEXT:    store i32 [[TMP1]], ptr @test12_a, align 4, !tbaa [[TBAA2]]
 // NO-SANITIZE-WITHOUT-ATTR-NEXT:    br label [[FOR_COND:%.*]]
 // NO-SANITIZE-WITHOUT-ATTR:       for.cond:
@@ -1188,7 +1188,7 @@ struct test13_bar {
 // SANITIZE-WITH-ATTR-NEXT:    [[TMP2:%.*]] = icmp ugt i64 [[TMP1]], [[INDEX]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    br i1 [[TMP2]], label [[CONT5:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       handler.out_of_bounds:
-// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB23:[0-9]+]], i64 [[INDEX]]) #[[ATTR10]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB24:[0-9]+]], i64 [[INDEX]]) #[[ATTR10]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    unreachable, !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       cont5:
 // SANITIZE-WITH-ATTR-NEXT:    [[REVMAP:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 16
@@ -1249,7 +1249,7 @@ struct test14_foo {
 // SANITIZE-WITH-ATTR-NEXT:    br i1 [[TMP0]], label [[TRAP:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       handler.out_of_bounds:
 // SANITIZE-WITH-ATTR-NEXT:    [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64
-// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB24:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB25:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    unreachable, !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       trap:
 // SANITIZE-WITH-ATTR-NEXT:    tail call void @llvm.trap() #[[ATTR10]]
@@ -1305,7 +1305,7 @@ int test14(int idx) {
 // SANITIZE-WITH-ATTR-NEXT:    br i1 [[TMP0]], label [[TRAP:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       handler.out_of_bounds:
 // SANITIZE-WITH-ATTR-NEXT:    [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64
-// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB25:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB27:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR-NEXT:    unreachable, !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       trap:
 // SANITIZE-WITH-ATTR-NEXT:    tail call void @llvm.trap() #[[ATTR10]]
@@ -1315,7 +1315,7 @@ int test14(int idx) {
 // NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR4]] {
 // NO-SANITIZE-WITH-ATTR-NEXT:  entry:
 // NO-SANITIZE-WITH-ATTR-NEXT:    [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64
-// NO-SANITIZE-WITH-ATTR-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr getelementptr inbounds ([[STRUCT_ANON_8:%.*]], ptr @__const.test15.foo, i64 1, i32 0), i64 0, i64 [[IDXPROM]]
+// NO-SANITIZE-WITH-ATTR-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr getelementptr inbounds (i8, ptr @__const.test15.foo, i64 8), i64 0, i64 [[IDXPROM]]
 // NO-SANITIZE-WITH-ATTR-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]]
 // NO-SANITIZE-WITH-ATTR-NEXT:    ret i32 [[TMP0]]
 //
@@ -1326,7 +1326,7 @@ int test14(int idx) {
 // SANITIZE-WITHOUT-ATTR-NEXT:    br i1 [[TMP0]], label [[TRAP:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8]], !nosanitize [[META9]]
 // SANITIZE-WITHOUT-ATTR:       handler.out_of_bounds:
 // SANITIZE-WITHOUT-ATTR-NEXT:    [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64
-// SANITIZE-WITHOUT-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB10:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META9]]
+// SANITIZE-WITHOUT-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB11:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META9]]
 // SANITIZE-WITHOUT-ATTR-NEXT:    unreachable, !nosanitize [[META9]]
 // SANITIZE-WITHOUT-ATTR:       trap:
 // SANITIZE-WITHOUT-ATTR-NEXT:    tail call void @llvm.trap() #[[ATTR8]]
@@ -1336,7 +1336,7 @@ int test14(int idx) {
 // NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR1]] {
 // NO-SANITIZE-WITHOUT-ATTR-NEXT:  entry:
 // NO-SANITIZE-WITHOUT-ATTR-NEXT:    [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64
-// NO-SANITIZE-WITHOUT-ATTR-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr getelementptr inbounds ([[STRUCT_ANON_8:%.*]], ptr @__const.test15.foo, i64 1, i32 0), i64 0, i64 [[IDXPROM]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr getelementptr inbounds (i8, ptr @__const.test15.foo, i64 8), i64 0, i64 [[IDXPROM]]
 // NO-SANITIZE-WITHOUT-ATTR-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]]
 // NO-SANITIZE-WITHOUT-ATTR-NEXT:    ret i32 [[TMP0]]
 //
@@ -1487,7 +1487,7 @@ struct tests_foo {
 // SANITIZE-WITH-ATTR-NEXT:    [[TMP0:%.*]] = icmp ugt i32 [[DOTCOUNTED_BY_LOAD]], 10
 // SANITIZE-WITH-ATTR-NEXT:    br i1 [[TMP0]], label [[CONT4:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
 // SANITIZE-WITH-ATTR:       handler.out_of_bounds:
-// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB26:[0-9]+]], i64 10) #[[ATTR10]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT:    tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB28:[0-9]+]], i64 10) #[[ATTR10]], !nosanitize [[M...
[truncated]

bool CanBeNull, CanBeFreed;
uint64_t DerefBytes =
Ptr->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
InBounds = DerefBytes != 0 && !CanBeNull && Offset.sle(DerefBytes);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added this inference in this patch, because we lose out on this inference in the DataLayout-independent constant folding:

// If all indices are known integers and normalized, we can do a simple
// check for the "inbounds" property.
if (!Unknown && !InBounds)
if (auto *GV = dyn_cast<GlobalVariable>(C))
if (!GV->hasExternalWeakLinkage() && GV->getValueType() == PointeeTy &&
isInBoundsIndices(Idxs))
return ConstantExpr::getGetElementPtr(PointeeTy, C, Idxs,
/*InBounds=*/true, InRange);
As such, we need a (more powerful version of) this inference in the DataLayout-aware constant folding code.

Copy link
Contributor

Choose a reason for hiding this comment

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

can we remove the other constant folding?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think we'd want to remove it at this point as it's still used in some key places like initial IR construction in clang -- longer term, I'd like to get rid of the two separate constant folding implementations altogether.

@Narutoworld
Copy link
Contributor

Hi @nikic
I read this RFC https://discourse.llvm.org/t/rfc-replacing-getelementptr-with-ptradd/68699 and it seems it reqires multiple patches to implement it.
I am wondering if you have a link or page which contains all related PRs (or future PRs) ?
I want to track its progess.

@nikic
Copy link
Contributor Author

nikic commented Apr 25, 2024

Hi @nikic I read this RFC https://discourse.llvm.org/t/rfc-replacing-getelementptr-with-ptradd/68699 and it seems it reqires multiple patches to implement it. I am wondering if you have a link or page which contains all related PRs (or future PRs) ? I want to track its progess.

The major patches have been #68882, #84341 and this one. There have been some smaller changes in between to fix related optimization regressions.

@nikic nikic force-pushed the constexpr-gep-i8-canon branch from e78a5eb to 2fa7299 Compare April 26, 2024 04:54
@llvmbot llvmbot added compiler-rt PGO Profile Guided Optimizations labels Apr 26, 2024
Copy link

github-actions bot commented Apr 26, 2024

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff f6527774569790b5a5236f6e84f3f839ce6c2fff 10ed97d2fd16475736b7d2f7b67a4e3e4e0406a1 -- clang/test/CodeGen/RISCV/riscv-inline-asm.c clang/test/CodeGen/attr-counted-by.c clang/test/CodeGenCXX/atomicinit.cpp clang/test/CodeGenCXX/auto-var-init.cpp clang/test/Profile/c-unreachable-after-switch.c compiler-rt/test/profile/Linux/counter_promo_for.c compiler-rt/test/profile/Linux/counter_promo_while.c llvm/lib/Analysis/ConstantFolding.cpp
View the diff from clang-format here.
diff --git a/compiler-rt/test/profile/Linux/counter_promo_for.c b/compiler-rt/test/profile/Linux/counter_promo_for.c
index aa77e6084b..d843510697 100644
--- a/compiler-rt/test/profile/Linux/counter_promo_for.c
+++ b/compiler-rt/test/profile/Linux/counter_promo_for.c
@@ -18,30 +18,30 @@ int g;
 __attribute__((noinline)) void bar(int i) { g += i; }
 
 __attribute__((noinline)) void foo(int n, int N) {
-// PROMO-LABEL: @foo
-// PROMO: load{{.*}}@__profc_foo{{.*}} 24){{.*}}
-// PROMO-NEXT: add
-// PROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 24){{.*}}
-// PROMO: load{{.*}}@__profc_foo, align
-// PROMO-NEXT: add
-// PROMO-NEXT: store{{.*}}@__profc_foo, align
-// PROMO-NEXT: load{{.*}}@__profc_foo{{.*}} 8){{.*}}
-// PROMO-NEXT: add
-// PROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 8){{.*}}
-// PROMO: load{{.*}}@__profc_foo{{.*}} 16){{.*}}
-// PROMO-NEXT: add
-// PROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 16){{.*}}
-//
-// NOPROMO-LABEL: @foo
-// NOPROMO: load{{.*}}@__profc_foo, align
-// NOPROMO-NEXT: add
-// NOPROMO-NEXT: store{{.*}}@__profc_foo, align
-// NOPROMO: load{{.*}}@__profc_foo{{.*}} 8){{.*}}
-// NOPROMO-NEXT: add
-// NOPROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 8){{.*}}
-// NOPROMO: load{{.*}}@__profc_foo{{.*}} 16){{.*}}
-// NOPROMO-NEXT: add
-// NOPROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 16){{.*}}
+  // PROMO-LABEL: @foo
+  // PROMO: load{{.*}}@__profc_foo{{.*}} 24){{.*}}
+  // PROMO-NEXT: add
+  // PROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 24){{.*}}
+  // PROMO: load{{.*}}@__profc_foo, align
+  // PROMO-NEXT: add
+  // PROMO-NEXT: store{{.*}}@__profc_foo, align
+  // PROMO-NEXT: load{{.*}}@__profc_foo{{.*}} 8){{.*}}
+  // PROMO-NEXT: add
+  // PROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 8){{.*}}
+  // PROMO: load{{.*}}@__profc_foo{{.*}} 16){{.*}}
+  // PROMO-NEXT: add
+  // PROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 16){{.*}}
+  //
+  // NOPROMO-LABEL: @foo
+  // NOPROMO: load{{.*}}@__profc_foo, align
+  // NOPROMO-NEXT: add
+  // NOPROMO-NEXT: store{{.*}}@__profc_foo, align
+  // NOPROMO: load{{.*}}@__profc_foo{{.*}} 8){{.*}}
+  // NOPROMO-NEXT: add
+  // NOPROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 8){{.*}}
+  // NOPROMO: load{{.*}}@__profc_foo{{.*}} 16){{.*}}
+  // NOPROMO-NEXT: add
+  // NOPROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 16){{.*}}
   int i;
   for (i = 0; i < N; i++) {
     if (i < n + 1)
diff --git a/compiler-rt/test/profile/Linux/counter_promo_while.c b/compiler-rt/test/profile/Linux/counter_promo_while.c
index c6ea3a7282..e0a9ee3c24 100644
--- a/compiler-rt/test/profile/Linux/counter_promo_while.c
+++ b/compiler-rt/test/profile/Linux/counter_promo_while.c
@@ -16,27 +16,27 @@
 int g;
 __attribute__((noinline)) void bar(int i) { g += i; }
 __attribute__((noinline)) void foo(int n, int N) {
-// PROMO-LABEL: @foo
-// PROMO: load{{.*}}@__profc_foo, align
-// PROMO-NEXT: add
-// PROMO-NEXT: store{{.*}}@__profc_foo, align
-// PROMO-NEXT: load{{.*}}@__profc_foo{{.*}} 8){{.*}}
-// PROMO-NEXT: add
-// PROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 8){{.*}}
-// PROMO-NEXT: load{{.*}}@__profc_foo{{.*}} 16){{.*}}
-// PROMO-NEXT: add
-// PROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 16){{.*}}
-//
-// NOPROMO-LABEL: @foo
-// NOPROMO: load{{.*}}@__profc_foo, align
-// NOPROMO-NEXT: add
-// NOPROMO-NEXT: store{{.*}}@__profc_foo, align
-// NOPROMO: load{{.*}}@__profc_foo{{.*}} 8){{.*}}
-// NOPROMO-NEXT: add
-// NOPROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 8){{.*}}
-// NOPROMO: load{{.*}}@__profc_foo{{.*}} 16){{.*}}
-// NOPROMO-NEXT: add
-// NOPROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 16){{.*}}
+  // PROMO-LABEL: @foo
+  // PROMO: load{{.*}}@__profc_foo, align
+  // PROMO-NEXT: add
+  // PROMO-NEXT: store{{.*}}@__profc_foo, align
+  // PROMO-NEXT: load{{.*}}@__profc_foo{{.*}} 8){{.*}}
+  // PROMO-NEXT: add
+  // PROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 8){{.*}}
+  // PROMO-NEXT: load{{.*}}@__profc_foo{{.*}} 16){{.*}}
+  // PROMO-NEXT: add
+  // PROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 16){{.*}}
+  //
+  // NOPROMO-LABEL: @foo
+  // NOPROMO: load{{.*}}@__profc_foo, align
+  // NOPROMO-NEXT: add
+  // NOPROMO-NEXT: store{{.*}}@__profc_foo, align
+  // NOPROMO: load{{.*}}@__profc_foo{{.*}} 8){{.*}}
+  // NOPROMO-NEXT: add
+  // NOPROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 8){{.*}}
+  // NOPROMO: load{{.*}}@__profc_foo{{.*}} 16){{.*}}
+  // NOPROMO-NEXT: add
+  // NOPROMO-NEXT: store{{.*}}@__profc_foo{{.*}} 16){{.*}}
   int i = 0;
   while (i < N) {
     if (i < n + 1)

Indices.push_back(APInt::getZero(isa<StructType>(ElemTy) ? 32 : BitWidth));
ElemTy = NextTy;
// Try to infer inbounds for GEPs of globals.
if (!InBounds && Offset.isNonNegative()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

is there a test for the case where !Offset.isNonNegative()?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@aeubanks
Copy link
Contributor

btw we're still looking into a performance regression caused by #68882 that still repros with LLVM head, even after the SROA enhancements. this patch looks good, but can we hold off a bit on submitting this?

@nikic
Copy link
Contributor Author

nikic commented Apr 29, 2024

btw we're still looking into a performance regression caused by #68882 that still repros with LLVM head, even after the SROA enhancements. this patch looks good, but can we hold off a bit on submitting this?

Sure!

Copy link
Contributor

@aeubanks aeubanks left a comment

Choose a reason for hiding this comment

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

we've resolved the performance regression from the previous patch internally, thanks for waiting!

nikic added 2 commits May 20, 2024 09:42
This patch canonicalizes constant expression GEPs to use i8 source
element type, aka ptradd. This is the ConstantFolding equivalent of
the InstCombine canonicalization introduced in llvm#68882.

I believe all our optimizations working on constant expression GEPs
(like GlobalOpt etc) have already been switched to work on offsets,
so I don't expect any significant fallout from this change.

This is part of:
https://discourse.llvm.org/t/rfc-replacing-getelementptr-with-ptradd/68699
@nikic nikic force-pushed the constexpr-gep-i8-canon branch from 2fa7299 to 10ed97d Compare May 20, 2024 07:46
@nikic nikic merged commit 8e8d259 into llvm:main May 20, 2024
3 of 4 checks passed
@nikic nikic deleted the constexpr-gep-i8-canon branch May 20, 2024 09:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants