Index: llvm/lib/CodeGen/CodeGenPrepare.cpp =================================================================== --- llvm/lib/CodeGen/CodeGenPrepare.cpp +++ llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -5108,6 +5108,12 @@ WeakTrackingVH IterHandle(CurValue); BasicBlock *BB = CurInstIterator->getParent(); + // These maps can have an AssertingVH to a GEP that gets recursively + // deleted below; see PR43269. Clearing them is okay: since we return + // true below, the optimization will be re-run. + LargeOffsetGEPMap.clear(); + LargeOffsetGEPID.clear(); + RecursivelyDeleteTriviallyDeadInstructions(Repl, TLInfo); if (IterHandle != CurValue) { Index: llvm/test/Transforms/CodeGenPrepare/AArch64/large-offset-gep-pr43269.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/CodeGenPrepare/AArch64/large-offset-gep-pr43269.ll @@ -0,0 +1,52 @@ +; RUN: opt -mtriple=aarch64-linux-gnu --codegenprepare -S %s | FileCheck %s + +; Just don't crash, see PR43269. +; CHECK: @t + +%struct.f = type { [1024 x %struct.b] } +%struct.b = type { i32, i32, i32, i32 } +@o = common local_unnamed_addr global i32 0, align 4 +@p = common local_unnamed_addr global i32 0, align 4 +@j = common global %struct.f zeroinitializer, align 4 + + +define i32 @t() local_unnamed_addr { +entry: + %call = tail call i8* bitcast (i8* (...)* @s to i8* ()*)() + %0 = load i32, i32* @o, align 4 + %tobool = icmp eq i32 %0, 0 + br i1 %tobool, label %if.end, label %bad + +if.end: + %n = getelementptr inbounds i8, i8* %call, i64 16392 + %1 = bitcast i8* %n to i32* + %2 = load i32, i32* @p, align 4 + %m = getelementptr inbounds i8, i8* %call, i64 16384 + %arrayidx = bitcast i8* %m to i8** + %call5 = tail call i32 bitcast (i32 (...)* @q to i32 (i32, i32, i32, void (%struct.f*, ...)*, i32, %struct.f*, i8**)*)(i32 0, i32 %2, i32 0, void (%struct.f*, ...)* nonnull @h, i32 0, %struct.f* nonnull @j, i8** nonnull %arrayidx) + %call7 = tail call i32 bitcast (i32 (...)* @q to i32 ()*)() + %tobool8 = icmp eq i32 %call7, 0 + br i1 %tobool8, label %if.end10, label %if.then9 + +if.then9: + tail call void bitcast (void (...)* @r to void ()*)() + br label %if.end10 + +if.end10: + %3 = load i32, i32* %1, align 8 + %tobool12 = icmp eq i32 %3, 0 + %4 = load i32, i32* @p, align 4 + %arrayidx19 = bitcast i8* %m to i8** + %arrayidx19.sink = select i1 %tobool12, i8** %arrayidx19, i8** %arrayidx + %5 = load i8*, i8** %arrayidx19.sink, align 8 + tail call void bitcast (void (...)* @r to void (i32, i32, i8*)*)(i32 0, i32 %4, i8* %5) + br label %bad + +bad: + ret i32 0 +} + +declare i8* @s(...) +declare i32 @q(...) +declare void @h(%struct.f* sret %0, ...) +declare void @r(...)