Skip to content

[InstCombine] Don't look at ConstantData users #103302

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

Conversation

aengelke
Copy link
Contributor

When looking at PHI operand for combining, only look at instructions and
arguments. The loop later iteraters over Arg's users, which is not
useful if Arg is a constant -- it's users are not meaningful and might
be in different functions, which causes problems for the dominates()
query.

aengelke and others added 2 commits August 13, 2024 15:58
Created using spr 1.3.5-bogner
Created using spr 1.3.5-bogner

[skip ci]
@llvmbot
Copy link
Member

llvmbot commented Aug 13, 2024

@llvm/pr-subscribers-llvm-transforms

Author: Alexis Engelke (aengelke)

Changes

When looking at PHI operand for combining, only look at instructions and
arguments. The loop later iteraters over Arg's users, which is not
useful if Arg is a constant -- it's users are not meaningful and might
be in different functions, which causes problems for the dominates()
query.


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

2 Files Affected:

  • (modified) llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp (+4)
  • (added) llvm/test/Transforms/InstCombine/phi-int-users.ll (+576)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
index 86411320ab2487..bcff9a72b65724 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
@@ -143,6 +143,10 @@ bool InstCombinerImpl::foldIntegerTypedPHI(PHINode &PN) {
     BasicBlock *BB = std::get<0>(Incoming);
     Value *Arg = std::get<1>(Incoming);
 
+    // Arg could be a constant, constant expr, etc., which we don't cover here.
+    if (!isa<Instruction>(Arg) && !isa<Argument>(Arg))
+      return false;
+
     // First look backward:
     if (auto *PI = dyn_cast<PtrToIntInst>(Arg)) {
       AvailablePtrVals.emplace_back(PI->getOperand(0));
diff --git a/llvm/test/Transforms/InstCombine/phi-int-users.ll b/llvm/test/Transforms/InstCombine/phi-int-users.ll
new file mode 100644
index 00000000000000..ce81c5d7e36267
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/phi-int-users.ll
@@ -0,0 +1,576 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -mtriple=arm64 -passes='inline,function(sroa<modify-cfg>,jump-threading,instcombine)' -S < %s | FileCheck %s
+
+; Verify that instcombine doesn't look at users of Constant in different
+; functions for dominates() queries.
+
+%struct.widget = type { %struct.baz, i8, [7 x i8] }
+%struct.baz = type { %struct.snork }
+%struct.snork = type { [8 x i8] }
+
+define void @spam(ptr %arg) {
+; CHECK-LABEL: define void @spam(
+; CHECK-SAME: ptr [[ARG:%.*]]) personality ptr null {
+; CHECK-NEXT:  [[BB:.*:]]
+; CHECK-NEXT:    [[LOAD_I:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I]], label %[[BB2_I:.*]], label %[[BB3_I:.*]]
+; CHECK:       [[BB2_I]]:
+; CHECK-NEXT:    store i64 1, ptr [[ARG]], align 8
+; CHECK-NEXT:    br label %[[BARNEY_EXIT:.*]]
+; CHECK:       [[BB3_I]]:
+; CHECK-NEXT:    [[LOAD_I_I:%.*]] = load volatile i32, ptr null, align 4
+; CHECK-NEXT:    [[ICMP_I_I:%.*]] = icmp eq i32 [[LOAD_I_I]], 0
+; CHECK-NEXT:    br i1 [[ICMP_I_I]], label %[[BB2_I_I:.*]], label %[[BB3_I_I:.*]]
+; CHECK:       [[BB2_I_I]]:
+; CHECK-NEXT:    br label %[[BB1_I:.*]]
+; CHECK:       [[BB1_I]]:
+; CHECK-NEXT:    [[LOAD_I_I_I:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I_I_I]], label %[[SPAM_EXIT_I:.*]], label %[[BB3_I_I_I:.*]]
+; CHECK:       [[BB3_I_I_I]]:
+; CHECK-NEXT:    call void @zot.4()
+; CHECK-NEXT:    br label %[[SPAM_EXIT_I]]
+; CHECK:       [[SPAM_EXIT_I]]:
+; CHECK-NEXT:    [[ALLOCA_SROA_0_1_I:%.*]] = phi i64 [ 0, %[[BB3_I_I_I]] ], [ 1, %[[BB1_I]] ]
+; CHECK-NEXT:    [[TMP0:%.*]] = inttoptr i64 [[ALLOCA_SROA_0_1_I]] to ptr
+; CHECK-NEXT:    store i32 0, ptr [[TMP0]], align 4
+; CHECK-NEXT:    br label %[[BB1_I]]
+; CHECK:       [[EGGS_EXIT:.*:]]
+; CHECK-NEXT:    br label %[[BARNEY_EXIT]]
+; CHECK:       [[BB3_I_I]]:
+; CHECK-NEXT:    [[LOAD_I_I1:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I_I1]], label %[[QUUX_EXIT:.*]], label %[[BB3_I_I2:.*]]
+; CHECK:       [[BB3_I_I2]]:
+; CHECK-NEXT:    call void @snork()
+; CHECK-NEXT:    unreachable
+; CHECK:       [[QUUX_EXIT]]:
+; CHECK-NEXT:    store ptr poison, ptr null, align 8
+; CHECK-NEXT:    br label %[[BARNEY_EXIT]]
+; CHECK:       [[BARNEY_EXIT]]:
+; CHECK-NEXT:    ret void
+;
+bb:
+  call void @barney(ptr %arg)
+  ret void
+}
+
+define ptr @zot(ptr %arg) {
+; CHECK-LABEL: define ptr @zot(
+; CHECK-SAME: ptr [[ARG:%.*]]) personality ptr null {
+; CHECK-NEXT:  [[BB:.*:]]
+; CHECK-NEXT:    [[LOAD_I_I_I_I:%.*]] = load ptr, ptr [[ARG]], align 8
+; CHECK-NEXT:    store ptr null, ptr [[ARG]], align 8
+; CHECK-NEXT:    store i32 0, ptr [[LOAD_I_I_I_I]], align 4
+; CHECK-NEXT:    ret ptr null
+;
+bb:
+  %call = call ptr @ham.8(ptr %arg)
+  ret ptr null
+}
+
+define void @wombat() personality ptr null {
+; CHECK-LABEL: define void @wombat() personality ptr null {
+; CHECK-NEXT:  [[BB:.*:]]
+; CHECK-NEXT:    call void @snork()
+; CHECK-NEXT:    unreachable
+;
+bb:
+  call void @snork()
+  unreachable
+}
+
+define ptr @wombat.1(ptr %arg) {
+; CHECK-LABEL: define ptr @wombat.1(
+; CHECK-SAME: ptr [[ARG:%.*]]) {
+; CHECK-NEXT:  [[BB:.*:]]
+; CHECK-NEXT:    store i64 1, ptr [[ARG]], align 8
+; CHECK-NEXT:    ret ptr null
+;
+bb:
+  %call = call ptr @foo.9(ptr %arg)
+  ret ptr null
+}
+
+define void @quux() personality ptr null {
+; CHECK-LABEL: define void @quux() personality ptr null {
+; CHECK-NEXT:  [[BB:.*:]]
+; CHECK-NEXT:    [[LOAD_I:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I]], label %[[WIBBLE_EXIT:.*]], label %[[BB3_I:.*]]
+; CHECK:       [[BB3_I]]:
+; CHECK-NEXT:    call void @snork()
+; CHECK-NEXT:    unreachable
+; CHECK:       [[WIBBLE_EXIT]]:
+; CHECK-NEXT:    store ptr poison, ptr null, align 8
+; CHECK-NEXT:    ret void
+;
+bb:
+  call void @wobble()
+  ret void
+}
+
+define void @wobble() personality ptr null {
+; CHECK-LABEL: define void @wobble() personality ptr null {
+; CHECK-NEXT:  [[BB:.*:]]
+; CHECK-NEXT:    [[LOAD_I_I:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I_I]], label %[[WOBBLE_2_EXIT:.*]], label %[[BB3_I_I:.*]]
+; CHECK:       [[BB3_I_I]]:
+; CHECK-NEXT:    call void @snork()
+; CHECK-NEXT:    unreachable
+; CHECK:       [[WOBBLE_2_EXIT]]:
+; CHECK-NEXT:    store ptr poison, ptr null, align 8
+; CHECK-NEXT:    ret void
+;
+bb:
+  call void @quux.3()
+  ret void
+}
+
+define void @eggs() personality ptr null {
+; CHECK-LABEL: define void @eggs() personality ptr null {
+; CHECK-NEXT:  [[BB:.*:]]
+; CHECK-NEXT:    br label %[[BB1:.*]]
+; CHECK:       [[BB1]]:
+; CHECK-NEXT:    [[LOAD_I_I:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I_I]], label %[[SPAM_EXIT:.*]], label %[[BB3_I_I:.*]]
+; CHECK:       [[BB3_I_I]]:
+; CHECK-NEXT:    call void @zot.4()
+; CHECK-NEXT:    br label %[[SPAM_EXIT]]
+; CHECK:       [[SPAM_EXIT]]:
+; CHECK-NEXT:    [[ALLOCA_SROA_0_1:%.*]] = phi i64 [ 0, %[[BB3_I_I]] ], [ 1, %[[BB1]] ]
+; CHECK-NEXT:    [[TMP0:%.*]] = inttoptr i64 [[ALLOCA_SROA_0_1]] to ptr
+; CHECK-NEXT:    store i32 0, ptr [[TMP0]], align 4
+; CHECK-NEXT:    br label %[[BB1]]
+;
+bb:
+  %alloca = alloca %struct.widget, align 8
+  br label %bb1
+
+bb1:                                              ; preds = %bb1, %bb
+  call void @spam(ptr %alloca)
+  %call = call ptr @zot(ptr %alloca)
+  br label %bb1
+}
+
+define void @wobble.2() personality ptr null {
+; CHECK-LABEL: define void @wobble.2() personality ptr null {
+; CHECK-NEXT:  [[BB:.*:]]
+; CHECK-NEXT:    [[LOAD_I:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I]], label %[[BB2_I:.*]], label %[[BB3_I:.*]]
+; CHECK:       [[BB2_I]]:
+; CHECK-NEXT:    store ptr poison, ptr null, align 8
+; CHECK-NEXT:    br label %[[WIBBLE_EXIT:.*]]
+; CHECK:       [[BB3_I]]:
+; CHECK-NEXT:    call void @snork()
+; CHECK-NEXT:    unreachable
+; CHECK:       [[FOO_EXIT:.*:]]
+; CHECK-NEXT:    br label %[[WIBBLE_EXIT]]
+; CHECK:       [[WIBBLE_EXIT]]:
+; CHECK-NEXT:    ret void
+;
+bb:
+  call void @wibble(ptr null)
+  ret void
+}
+
+define void @quux.3() personality ptr null {
+; CHECK-LABEL: define void @quux.3() personality ptr null {
+; CHECK-NEXT:  [[BB:.*:]]
+; CHECK-NEXT:    [[LOAD_I:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I]], label %[[BB2_I:.*]], label %[[BB3_I:.*]]
+; CHECK:       [[BB2_I]]:
+; CHECK-NEXT:    store ptr poison, ptr null, align 8
+; CHECK-NEXT:    br label %[[WIBBLE_EXIT:.*]]
+; CHECK:       [[BB3_I]]:
+; CHECK-NEXT:    call void @snork()
+; CHECK-NEXT:    unreachable
+; CHECK:       [[WOMBAT_EXIT:.*:]]
+; CHECK-NEXT:    br label %[[WIBBLE_EXIT]]
+; CHECK:       [[WIBBLE_EXIT]]:
+; CHECK-NEXT:    ret void
+;
+bb:
+  call void @wobble.2()
+  ret void
+}
+
+define void @zot.4() personality ptr null {
+; CHECK-LABEL: define void @zot.4() personality ptr null {
+; CHECK-NEXT:  [[BB:.*:]]
+; CHECK-NEXT:    [[LOAD_I:%.*]] = load volatile i32, ptr null, align 4
+; CHECK-NEXT:    [[ICMP_I:%.*]] = icmp eq i32 [[LOAD_I]], 0
+; CHECK-NEXT:    br i1 [[ICMP_I]], label %[[BB2_I:.*]], label %[[BB3_I:.*]]
+; CHECK:       [[BB2_I]]:
+; CHECK-NEXT:    br label %[[BB1_I:.*]]
+; CHECK:       [[BB1_I]]:
+; CHECK-NEXT:    [[LOAD_I_I_I:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I_I_I]], label %[[SPAM_EXIT_I:.*]], label %[[BB3_I_I_I:.*]]
+; CHECK:       [[BB3_I_I_I]]:
+; CHECK-NEXT:    call void @zot.4()
+; CHECK-NEXT:    br label %[[SPAM_EXIT_I]]
+; CHECK:       [[SPAM_EXIT_I]]:
+; CHECK-NEXT:    [[ALLOCA_I_SROA_0_1:%.*]] = phi i64 [ 0, %[[BB3_I_I_I]] ], [ 1, %[[BB1_I]] ]
+; CHECK-NEXT:    [[TMP0:%.*]] = inttoptr i64 [[ALLOCA_I_SROA_0_1]] to ptr
+; CHECK-NEXT:    store i32 0, ptr [[TMP0]], align 4
+; CHECK-NEXT:    br label %[[BB1_I]]
+; CHECK:       [[EGGS_EXIT:.*:]]
+; CHECK-NEXT:    br label %[[BLAM_EXIT:.*]]
+; CHECK:       [[BB3_I]]:
+; CHECK-NEXT:    [[LOAD_I_I:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I_I]], label %[[BB2_I_I:.*]], label %[[BB3_I_I:.*]]
+; CHECK:       [[BB2_I_I]]:
+; CHECK-NEXT:    store ptr poison, ptr null, align 8
+; CHECK-NEXT:    br label %[[BLAM_EXIT]]
+; CHECK:       [[BB3_I_I]]:
+; CHECK-NEXT:    call void @snork()
+; CHECK-NEXT:    unreachable
+; CHECK:       [[WOMBAT_EXIT:.*:]]
+; CHECK-NEXT:    br label %[[BLAM_EXIT]]
+; CHECK:       [[BLAM_EXIT]]:
+; CHECK-NEXT:    ret void
+;
+bb:
+  call void @blam()
+  ret void
+}
+
+define void @blam() {
+; CHECK-LABEL: define void @blam() personality ptr null {
+; CHECK-NEXT:  [[BB:.*:]]
+; CHECK-NEXT:    [[LOAD:%.*]] = load volatile i32, ptr null, align 4
+; CHECK-NEXT:    [[ICMP:%.*]] = icmp eq i32 [[LOAD]], 0
+; CHECK-NEXT:    br i1 [[ICMP]], label %[[BB2:.*]], label %[[BB3:.*]]
+; CHECK:       [[BB1:.*]]:
+; CHECK-NEXT:    ret void
+; CHECK:       [[BB2]]:
+; CHECK-NEXT:    br label %[[BB1_I:.*]]
+; CHECK:       [[BB1_I]]:
+; CHECK-NEXT:    [[LOAD_I_I:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I_I]], label %[[SPAM_EXIT:.*]], label %[[BB3_I_I:.*]]
+; CHECK:       [[BB3_I_I]]:
+; CHECK-NEXT:    [[LOAD_I_I_I:%.*]] = load volatile i32, ptr null, align 4
+; CHECK-NEXT:    [[ICMP_I_I_I:%.*]] = icmp eq i32 [[LOAD_I_I_I]], 0
+; CHECK-NEXT:    br i1 [[ICMP_I_I_I]], label %[[BB2_I_I_I:.*]], label %[[BB3_I_I_I:.*]]
+; CHECK:       [[BB2_I_I_I]]:
+; CHECK-NEXT:    br label %[[BB1_I1:.*]]
+; CHECK:       [[BB1_I1]]:
+; CHECK-NEXT:    [[LOAD_I_I_I2:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I_I_I2]], label %[[SPAM_EXIT_I:.*]], label %[[BB3_I_I_I3:.*]]
+; CHECK:       [[BB3_I_I_I3]]:
+; CHECK-NEXT:    call void @zot.4()
+; CHECK-NEXT:    br label %[[SPAM_EXIT_I]]
+; CHECK:       [[SPAM_EXIT_I]]:
+; CHECK-NEXT:    [[ALLOCA_SROA_0_1_I:%.*]] = phi i64 [ 0, %[[BB3_I_I_I3]] ], [ 1, %[[BB1_I1]] ]
+; CHECK-NEXT:    [[TMP0:%.*]] = inttoptr i64 [[ALLOCA_SROA_0_1_I]] to ptr
+; CHECK-NEXT:    store i32 0, ptr [[TMP0]], align 4
+; CHECK-NEXT:    br label %[[BB1_I1]]
+; CHECK:       [[EGGS_EXIT4:.*]]:
+; CHECK-NEXT:    br label %[[SPAM_EXIT]]
+; CHECK:       [[BB3_I_I_I]]:
+; CHECK-NEXT:    [[LOAD_I_I5:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I_I5]], label %[[QUUX_EXIT:.*]], label %[[BB3_I_I6:.*]]
+; CHECK:       [[BB3_I_I6]]:
+; CHECK-NEXT:    call void @snork()
+; CHECK-NEXT:    unreachable
+; CHECK:       [[QUUX_EXIT]]:
+; CHECK-NEXT:    store ptr poison, ptr null, align 8
+; CHECK-NEXT:    br label %[[SPAM_EXIT]]
+; CHECK:       [[SPAM_EXIT]]:
+; CHECK-NEXT:    [[ALLOCA_I_SROA_0_1:%.*]] = phi i64 [ 1, %[[BB1_I]] ], [ 0, %[[QUUX_EXIT]] ], [ 0, %[[EGGS_EXIT4]] ]
+; CHECK-NEXT:    [[TMP1:%.*]] = inttoptr i64 [[ALLOCA_I_SROA_0_1]] to ptr
+; CHECK-NEXT:    store i32 0, ptr [[TMP1]], align 4
+; CHECK-NEXT:    br label %[[BB1_I]]
+; CHECK:       [[EGGS_EXIT:.*:]]
+; CHECK-NEXT:    br label %[[BB1]]
+; CHECK:       [[BB3]]:
+; CHECK-NEXT:    [[LOAD_I_I7:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I_I7]], label %[[WOBBLE_2_EXIT:.*]], label %[[BB3_I_I8:.*]]
+; CHECK:       [[BB3_I_I8]]:
+; CHECK-NEXT:    call void @snork()
+; CHECK-NEXT:    unreachable
+; CHECK:       [[WOBBLE_2_EXIT]]:
+; CHECK-NEXT:    store ptr poison, ptr null, align 8
+; CHECK-NEXT:    br label %[[BB1]]
+;
+bb:
+  %load = load volatile i32, ptr null, align 4
+  %icmp = icmp eq i32 %load, 0
+  br i1 %icmp, label %bb2, label %bb3
+
+bb1:                                              ; preds = %bb3, %bb2
+  ret void
+
+bb2:                                              ; preds = %bb
+  call void @eggs()
+  br label %bb1
+
+bb3:                                              ; preds = %bb
+  call void @quux()
+  br label %bb1
+}
+
+define void @barney(ptr %arg) personality ptr null {
+; CHECK-LABEL: define void @barney(
+; CHECK-SAME: ptr [[ARG:%.*]]) personality ptr null {
+; CHECK-NEXT:  [[BB:.*:]]
+; CHECK-NEXT:    [[LOAD:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD]], label %[[BB2:.*]], label %[[BB3:.*]]
+; CHECK:       [[BB1:.*]]:
+; CHECK-NEXT:    ret void
+; CHECK:       [[BB2]]:
+; CHECK-NEXT:    store i64 1, ptr [[ARG]], align 8
+; CHECK-NEXT:    br label %[[BB1]]
+; CHECK:       [[BB3]]:
+; CHECK-NEXT:    [[LOAD_I:%.*]] = load volatile i32, ptr null, align 4
+; CHECK-NEXT:    [[ICMP_I:%.*]] = icmp eq i32 [[LOAD_I]], 0
+; CHECK-NEXT:    br i1 [[ICMP_I]], label %[[BB2_I:.*]], label %[[BB3_I:.*]]
+; CHECK:       [[BB2_I]]:
+; CHECK-NEXT:    br label %[[BB1_I_I:.*]]
+; CHECK:       [[BB1_I_I]]:
+; CHECK-NEXT:    [[LOAD_I_I_I:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I_I_I]], label %[[SPAM_EXIT_I:.*]], label %[[BB3_I_I_I:.*]]
+; CHECK:       [[BB3_I_I_I]]:
+; CHECK-NEXT:    [[LOAD_I_I_I_I:%.*]] = load volatile i32, ptr null, align 4
+; CHECK-NEXT:    [[ICMP_I_I_I_I:%.*]] = icmp eq i32 [[LOAD_I_I_I_I]], 0
+; CHECK-NEXT:    br i1 [[ICMP_I_I_I_I]], label %[[BB2_I_I_I_I:.*]], label %[[BB3_I_I_I_I:.*]]
+; CHECK:       [[BB2_I_I_I_I]]:
+; CHECK-NEXT:    br label %[[BB1_I1_I:.*]]
+; CHECK:       [[BB1_I1_I]]:
+; CHECK-NEXT:    [[LOAD_I_I_I2_I:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I_I_I2_I]], label %[[SPAM_EXIT_I_I:.*]], label %[[BB3_I_I_I3_I:.*]]
+; CHECK:       [[BB3_I_I_I3_I]]:
+; CHECK-NEXT:    call void @zot.4()
+; CHECK-NEXT:    br label %[[SPAM_EXIT_I_I]]
+; CHECK:       [[SPAM_EXIT_I_I]]:
+; CHECK-NEXT:    [[ALLOCA_SROA_0_1_I_I:%.*]] = phi i64 [ 0, %[[BB3_I_I_I3_I]] ], [ 1, %[[BB1_I1_I]] ]
+; CHECK-NEXT:    [[TMP0:%.*]] = inttoptr i64 [[ALLOCA_SROA_0_1_I_I]] to ptr
+; CHECK-NEXT:    store i32 0, ptr [[TMP0]], align 4
+; CHECK-NEXT:    br label %[[BB1_I1_I]]
+; CHECK:       [[BB3_I_I_I_I]]:
+; CHECK-NEXT:    [[LOAD_I_I5_I:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I_I5_I]], label %[[QUUX_EXIT_I:.*]], label %[[BB3_I_I6_I:.*]]
+; CHECK:       [[BB3_I_I6_I]]:
+; CHECK-NEXT:    call void @snork()
+; CHECK-NEXT:    unreachable
+; CHECK:       [[QUUX_EXIT_I]]:
+; CHECK-NEXT:    store ptr poison, ptr null, align 8
+; CHECK-NEXT:    br label %[[SPAM_EXIT_I]]
+; CHECK:       [[SPAM_EXIT_I]]:
+; CHECK-NEXT:    [[ALLOCA_I_SROA_0_1_I:%.*]] = phi i64 [ 1, %[[BB1_I_I]] ], [ 0, %[[QUUX_EXIT_I]] ]
+; CHECK-NEXT:    [[TMP1:%.*]] = inttoptr i64 [[ALLOCA_I_SROA_0_1_I]] to ptr
+; CHECK-NEXT:    store i32 0, ptr [[TMP1]], align 4
+; CHECK-NEXT:    br label %[[BB1_I_I]]
+; CHECK:       [[BB3_I]]:
+; CHECK-NEXT:    [[LOAD_I_I7_I:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I_I7_I]], label %[[BLAM_EXIT:.*]], label %[[BB3_I_I8_I:.*]]
+; CHECK:       [[BB3_I_I8_I]]:
+; CHECK-NEXT:    call void @snork()
+; CHECK-NEXT:    unreachable
+; CHECK:       [[BLAM_EXIT]]:
+; CHECK-NEXT:    store ptr poison, ptr null, align 8
+; CHECK-NEXT:    br label %[[BB1]]
+;
+bb:
+  %load = load volatile i1, ptr null, align 1
+  br i1 %load, label %bb2, label %bb3
+
+bb1:                                              ; preds = %bb3, %bb2
+  ret void
+
+bb2:                                              ; preds = %bb
+  %call = call ptr @wombat.1(ptr %arg)
+  br label %bb1
+
+bb3:                                              ; preds = %bb
+  call void @zot.4()
+  br label %bb1
+}
+
+define void @snork() personality ptr null {
+; CHECK-LABEL: define void @snork() personality ptr null {
+; CHECK-NEXT:  [[BB:.*:]]
+; CHECK-NEXT:    [[LOAD_I:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I]], label %[[BARNEY_EXIT:.*]], label %[[BB3_I:.*]]
+; CHECK:       [[BB3_I]]:
+; CHECK-NEXT:    [[LOAD_I1:%.*]] = load volatile i32, ptr null, align 4
+; CHECK-NEXT:    [[ICMP_I:%.*]] = icmp eq i32 [[LOAD_I1]], 0
+; CHECK-NEXT:    br i1 [[ICMP_I]], label %[[BB2_I3:.*]], label %[[BLAM_EXIT:.*]]
+; CHECK:       [[BB2_I3]]:
+; CHECK-NEXT:    br label %[[BB1_I_I:.*]]
+; CHECK:       [[BB1_I_I]]:
+; CHECK-NEXT:    [[LOAD_I_I_I:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I_I_I]], label %[[SPAM_EXIT_I:.*]], label %[[BB3_I_I_I:.*]]
+; CHECK:       [[BB3_I_I_I]]:
+; CHECK-NEXT:    [[LOAD_I_I_I_I:%.*]] = load volatile i32, ptr null, align 4
+; CHECK-NEXT:    [[ICMP_I_I_I_I:%.*]] = icmp eq i32 [[LOAD_I_I_I_I]], 0
+; CHECK-NEXT:    br i1 [[ICMP_I_I_I_I]], label %[[BB2_I_I_I_I:.*]], label %[[BB3_I_I_I_I:.*]]
+; CHECK:       [[BB2_I_I_I_I]]:
+; CHECK-NEXT:    br label %[[BB1_I:.*]]
+; CHECK:       [[BB1_I]]:
+; CHECK-NEXT:    [[LOAD_I_I_I6:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I_I_I6]], label %[[SPAM_EXIT_I8:.*]], label %[[BB3_I_I_I7:.*]]
+; CHECK:       [[BB3_I_I_I7]]:
+; CHECK-NEXT:    call void @zot.4()
+; CHECK-NEXT:    br label %[[SPAM_EXIT_I8]]
+; CHECK:       [[SPAM_EXIT_I8]]:
+; CHECK-NEXT:    [[ALLOCA_I_SROA_0_1:%.*]] = phi i64 [ 0, %[[BB3_I_I_I7]] ], [ 1, %[[BB1_I]] ]
+; CHECK-NEXT:    [[TMP0:%.*]] = inttoptr i64 [[ALLOCA_I_SROA_0_1]] to ptr
+; CHECK-NEXT:    store i32 0, ptr [[TMP0]], align 4
+; CHECK-NEXT:    br label %[[BB1_I]]
+; CHECK:       [[EGGS_EXIT:.*]]:
+; CHECK-NEXT:    br label %[[SPAM_EXIT_I]]
+; CHECK:       [[BB3_I_I_I_I]]:
+; CHECK-NEXT:    [[LOAD_I_I4:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I_I4]], label %[[QUUX_EXIT:.*]], label %[[BB3_I_I5:.*]]
+; CHECK:       [[BB3_I_I5]]:
+; CHECK-NEXT:    call void @snork()
+; CHECK-NEXT:    unreachable
+; CHECK:       [[QUUX_EXIT]]:
+; CHECK-NEXT:    store ptr poison, ptr null, align 8
+; CHECK-NEXT:    br label %[[SPAM_EXIT_I]]
+; CHECK:       [[SPAM_EXIT_I]]:
+; CHECK-NEXT:    [[ALLOCA_I_I_SROA_0_1:%.*]] = phi i64 [ 1, %[[BB1_I_I]] ], [ 0, %[[QUUX_EXIT]] ], [ 0, %[[EGGS_EXIT]] ]
+; CHECK-NEXT:    [[TMP1:%.*]] = inttoptr i64 [[ALLOCA_I_I_SROA_0_1]] to ptr
+; CHECK-NEXT:    store i32 0, ptr [[TMP1]], align 4
+; CHECK-NEXT:    br label %[[BB1_I_I]]
+; CHECK:       [[BLAM_EXIT]]:
+; CHECK-NEXT:    [[LOAD_I_I:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD_I_I]], label %[[BARNEY_EXIT]], label %[[BB3_I_I:.*]]
+; CHECK:       [[BB3_I_I]]:
+; CHECK-NEXT:    call void @snork()
+; CHECK-NEXT:    unreachable
+; CHECK:       [[BARNEY_EXIT]]:
+; CHECK-NEXT:    store ptr poison, ptr null, align 8
+; CHECK-NEXT:    ret void
+;
+bb:
+  call void @barney(ptr null)
+  ret void
+}
+
+define void @wibble(ptr %arg) personality ptr null {
+; CHECK-LABEL: define void @wibble(
+; CHECK-SAME: ptr [[ARG:%.*]]) personality ptr null {
+; CHECK-NEXT:  [[BB:.*:]]
+; CHECK-NEXT:    [[LOAD:%.*]] = load volatile i1, ptr null, align 1
+; CHECK-NEXT:    br i1 [[LOAD]], label %[[BB2:.*]], label %[[BB3:.*]]
+; CHECK:       [[BB1:.*]]:
+; CHECK-NEXT:    ret void
+; CHECK:       [[BB2]]:
+; CHECK-NEXT:    store ptr null, ptr [[ARG]], align 8
+; CHECK-NEXT:    br label %[[BB1]]
+; CHECK:       [[BB3]]:
+; CHECK-NEXT:    call void @snork()
+; CHECK-NEXT:    unreachable
+; CHECK:       [[WOMBAT_EXIT:.*:]]
+; CHECK-NEXT:    br label %[[BB1]]
+;
+bb:
+  %load = load volatile i1, ptr null, align 1
+  br i1 %load, label %bb2, label %bb3
+
+bb1:                                              ; preds = %bb3, %bb2
+  ret void
+
+bb2:                                              ; preds = %bb
+  %call = call i64 @zot.5(i64 0)
+  %inttoptr = inttoptr i64 %call to ptr
+  store ptr %inttoptr, ptr %arg, align 8
+  br label %bb1
+
+bb3:                                              ; preds = %bb
+  %call4 = call i64 @foo()
+ ...
[truncated]

Created using spr 1.3.5-bogner
Copy link
Contributor

Choose a reason for hiding this comment

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

This test still doesn't look anything approaching minimal. Please run it through llvm-reduce.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Fun fact, llvm-reduce crashed on the input due to this bug.

Created using spr 1.3.5-bogner
Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Contributor

@fhahn fhahn left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for the fix

topperc and others added 2 commits August 13, 2024 18:44
Created using spr 1.3.5-bogner

[skip ci]
Created using spr 1.3.5-bogner
@aengelke aengelke changed the base branch from users/aengelke/spr/main.instcombine-dont-look-at-constantdata-users to main August 13, 2024 18:44
@aengelke aengelke merged commit 5b40a05 into main Aug 13, 2024
4 of 6 checks passed
@aengelke aengelke deleted the users/aengelke/spr/instcombine-dont-look-at-constantdata-users branch August 13, 2024 18:44
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.

6 participants