[rtsan] Add fork/execve interceptors (#117198)
[llvm-project.git] / llvm / test / Transforms / MoveAutoInit / clobber.ll
blob09084b6ddc51bb35e907dd31849df302f4143590
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; Checks that move-auto-init can move instruction passed unclobbering memory
3 ; instructions.
4 ; RUN: opt < %s -S -passes='move-auto-init' -verify-memoryssa | FileCheck %s
6 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
8 define i32 @foo(i32 noundef %0, i32 noundef %1, i32 noundef %2) #0 {
9 ; CHECK-LABEL: @foo(
10 ; CHECK-NEXT:    [[TMP4:%.*]] = alloca [100 x i8], align 16
11 ; CHECK-NEXT:    [[TMP5:%.*]] = alloca [2 x i8], align 1
12 ; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds [100 x i8], ptr [[TMP4]], i64 0, i64 0
13 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 100, ptr nonnull [[TMP6]]) #[[ATTR3:[0-9]+]]
14 ; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds [2 x i8], ptr [[TMP5]], i64 0, i64 0
15 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 2, ptr nonnull [[TMP7]]) #[[ATTR3]]
16 ; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds [2 x i8], ptr [[TMP5]], i64 0, i64 1
17 ; CHECK-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[TMP1:%.*]], 0
18 ; CHECK-NEXT:    br i1 [[TMP9]], label [[TMP15:%.*]], label [[TMP10:%.*]]
19 ; CHECK:       10:
20 ; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr noundef nonnull align 16 dereferenceable(100) [[TMP6]], i8 -86, i64 100, i1 false), !annotation !0
21 ; CHECK-NEXT:    [[TMP11:%.*]] = sext i32 [[TMP0:%.*]] to i64
22 ; CHECK-NEXT:    [[TMP12:%.*]] = getelementptr inbounds [100 x i8], ptr [[TMP4]], i64 0, i64 [[TMP11]]
23 ; CHECK-NEXT:    store i8 12, ptr [[TMP12]], align 1
24 ; CHECK-NEXT:    [[TMP13:%.*]] = load i8, ptr [[TMP6]], align 16
25 ; CHECK-NEXT:    [[TMP14:%.*]] = sext i8 [[TMP13]] to i32
26 ; CHECK-NEXT:    br label [[TMP22:%.*]]
27 ; CHECK:       15:
28 ; CHECK-NEXT:    [[TMP16:%.*]] = icmp eq i32 [[TMP2:%.*]], 0
29 ; CHECK-NEXT:    br i1 [[TMP16]], label [[TMP22]], label [[TMP17:%.*]]
30 ; CHECK:       17:
31 ; CHECK-NEXT:    store i8 -86, ptr [[TMP7]], align 1, !annotation !0
32 ; CHECK-NEXT:    store i8 -86, ptr [[TMP8]], align 1, !annotation !0
33 ; CHECK-NEXT:    [[TMP18:%.*]] = sext i32 [[TMP0]] to i64
34 ; CHECK-NEXT:    [[TMP19:%.*]] = getelementptr inbounds [2 x i8], ptr [[TMP5]], i64 0, i64 [[TMP18]]
35 ; CHECK-NEXT:    store i8 12, ptr [[TMP19]], align 1
36 ; CHECK-NEXT:    [[TMP20:%.*]] = load i8, ptr [[TMP7]], align 1
37 ; CHECK-NEXT:    [[TMP21:%.*]] = sext i8 [[TMP20]] to i32
38 ; CHECK-NEXT:    br label [[TMP22]]
39 ; CHECK:       22:
40 ; CHECK-NEXT:    [[TMP23:%.*]] = phi i32 [ [[TMP14]], [[TMP10]] ], [ [[TMP21]], [[TMP17]] ], [ 0, [[TMP15]] ]
41 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 2, ptr nonnull [[TMP7]]) #[[ATTR3]]
42 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 100, ptr nonnull [[TMP6]]) #[[ATTR3]]
43 ; CHECK-NEXT:    ret i32 [[TMP23]]
46   %4 = alloca [100 x i8], align 16
47   %5 = alloca [2 x i8], align 1
48   %6 = getelementptr inbounds [100 x i8], ptr %4, i64 0, i64 0
49   call void @llvm.lifetime.start.p0(i64 100, ptr nonnull %6) #3
50   ; This memset must move.
51   call void @llvm.memset.p0.i64(ptr noundef nonnull align 16 dereferenceable(100) %6, i8 -86, i64 100, i1 false), !annotation !0
52   %7 = getelementptr inbounds [2 x i8], ptr %5, i64 0, i64 0
53   call void @llvm.lifetime.start.p0(i64 2, ptr nonnull %7) #3
54   ; This store must move.
55   store i8 -86, ptr %7, align 1, !annotation !0
56   %8 = getelementptr inbounds [2 x i8], ptr %5, i64 0, i64 1
57   ; This store must move.
58   store i8 -86, ptr %8, align 1, !annotation !0
59   %9 = icmp eq i32 %1, 0
60   br i1 %9, label %15, label %10
62 10:
63   %11 = sext i32 %0 to i64
64   %12 = getelementptr inbounds [100 x i8], ptr %4, i64 0, i64 %11
65   store i8 12, ptr %12, align 1
66   %13 = load i8, ptr %6, align 16
67   %14 = sext i8 %13 to i32
68   br label %22
70 15:
71   %16 = icmp eq i32 %2, 0
72   br i1 %16, label %22, label %17
74 17:
75   %18 = sext i32 %0 to i64
76   %19 = getelementptr inbounds [2 x i8], ptr %5, i64 0, i64 %18
77   store i8 12, ptr %19, align 1
78   %20 = load i8, ptr %7, align 1
79   %21 = sext i8 %20 to i32
80   br label %22
82 22:
83   %23 = phi i32 [ %14, %10 ], [ %21, %17 ], [ 0, %15 ]
84   call void @llvm.lifetime.end.p0(i64 2, ptr nonnull %7) #3
85   call void @llvm.lifetime.end.p0(i64 100, ptr nonnull %6) #3
86   ret i32 %23
89 declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1
91 declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #2
93 declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1
95 attributes #0 = { mustprogress nofree nosync nounwind readnone uwtable willreturn }
96 attributes #1 = { argmemonly mustprogress nofree nosync nounwind willreturn }
97 attributes #2 = { argmemonly mustprogress nofree nounwind willreturn writeonly }
98 attributes #3 = { nounwind }
100 !0 = !{!"auto-init"}