The MaybePromotable set keeps track of loads/stores for which promotion was not attempted yet. Normally, any load/stores that are promoted in the current iteration will be removed from this set, because they naturally MustAlias with the promoted value. However, if the source program has UB with metadata claiming that a store is NoAlias, while it is actually MustAlias, and multiple different pointers are promoted in the same iteration, it can happen that a store is removed that is still in the MaybePromotable set, causing a use-after-free. While this could be fixed by explicitly invalidating values in MaybePromotable in the LoopPromoter, I'm going with the more radical option of dropping the set entirely here and check all load/stores on each promotion iteration. As promotion, and especially repeated promotion, are quite rare, this doesn't seem to have any impact on compile-time. Fixes https://bugs.llvm.org/show_bug.cgi?id=50367.
44 lines
1.1 KiB
LLVM
44 lines
1.1 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -S -passes='loop-mssa(licm)' < %s | FileCheck %s
|
|
@e = external dso_local global i32*, align 8
|
|
|
|
define void @main() {
|
|
; CHECK-LABEL: @main(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[LOOP1:%.*]]
|
|
; CHECK: loop1:
|
|
; CHECK-NEXT: br label [[LOOP2:%.*]]
|
|
; CHECK: loop2:
|
|
; CHECK-NEXT: br i1 false, label [[LOOP2_LATCH:%.*]], label [[LOOP_LATCH:%.*]]
|
|
; CHECK: loop2.latch:
|
|
; CHECK-NEXT: br label [[LOOP2]]
|
|
; CHECK: loop.latch:
|
|
; CHECK-NEXT: br label [[LOOP1]]
|
|
;
|
|
entry:
|
|
br label %loop1
|
|
|
|
loop1:
|
|
br label %loop2
|
|
|
|
loop2:
|
|
br i1 undef, label %loop2.latch, label %loop.latch
|
|
|
|
loop2.latch:
|
|
store i32 0, i32* null, align 4
|
|
br label %loop2
|
|
|
|
loop.latch:
|
|
store i32* null, i32** @e, align 8, !tbaa !0
|
|
%ptr = load i32*, i32** @e, align 8, !tbaa !0
|
|
store i32 0, i32* %ptr, align 4, !tbaa !4
|
|
br label %loop1
|
|
}
|
|
|
|
!0 = !{!1, !1, i64 0}
|
|
!1 = !{!"any pointer", !2, i64 0}
|
|
!2 = !{!"omnipotent char", !3, i64 0}
|
|
!3 = !{!"Simple C/C++ TBAA"}
|
|
!4 = !{!5, !5, i64 0}
|
|
!5 = !{!"int", !2, i64 0}
|