Files
clang-p2996/llvm/test/Transforms/LICM/pr50367.ll
Nikita Popov e81334a754 [LICM] Remove MaybePromotable set (PR50367)
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.
2021-05-18 20:26:01 +02:00

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}