[rtsan] Add fork/execve interceptors (#117198)
[llvm-project.git] / llvm / test / Analysis / ValueTracking / deref-bitcast-of-gep.ll
blob672e7da39ee260be0cd94e5e0dd2532aaa10078f
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=licm < %s | FileCheck %s
4 ; Note: the !invariant.load is there just solely to let us call @use()
5 ; to add a fake use, and still have the aliasing work out.  The call
6 ; to @use(0) is just to provide a may-unwind exit out of the loop, so
7 ; that LICM cannot hoist out the load simply because it is guaranteed
8 ; to execute.
10 declare void @use(i32)
12 define void @f_0(ptr align 4 dereferenceable(1024) %ptr) nofree nosync {
13 ; CHECK-LABEL: @f_0(
14 ; CHECK-NEXT:  entry:
15 ; CHECK-NEXT:    [[PTR_GEP:%.*]] = getelementptr i8, ptr [[PTR:%.*]], i32 32
16 ; CHECK-NEXT:    [[VAL:%.*]] = load i32, ptr [[PTR_GEP]], align 4
17 ; CHECK-NEXT:    br label [[LOOP:%.*]]
18 ; CHECK:       loop:
19 ; CHECK-NEXT:    call void @use(i32 0)
20 ; CHECK-NEXT:    call void @use(i32 [[VAL]])
21 ; CHECK-NEXT:    br label [[LOOP]]
25 entry:
26   %ptr.gep = getelementptr i8, ptr %ptr, i32 32
27   br label %loop
29 loop:
30   call void @use(i32 0)
31   %val = load i32, ptr %ptr.gep, !invariant.load !{}
32   call void @use(i32 %val)
33   br label %loop
36 define void @f_1(ptr align 4 dereferenceable_or_null(1024) %ptr) nofree nosync {
37 ; CHECK-LABEL: @f_1(
38 ; CHECK-NEXT:  entry:
39 ; CHECK-NEXT:    [[PTR_GEP:%.*]] = getelementptr i8, ptr [[PTR:%.*]], i32 32
40 ; CHECK-NEXT:    [[PTR_IS_NULL:%.*]] = icmp eq ptr [[PTR]], null
41 ; CHECK-NEXT:    br i1 [[PTR_IS_NULL]], label [[LEAVE:%.*]], label [[LOOP_PREHEADER:%.*]]
42 ; CHECK:       loop.preheader:
43 ; CHECK-NEXT:    [[VAL:%.*]] = load i32, ptr [[PTR_GEP]], align 4
44 ; CHECK-NEXT:    br label [[LOOP:%.*]]
45 ; CHECK:       loop:
46 ; CHECK-NEXT:    call void @use(i32 0)
47 ; CHECK-NEXT:    call void @use(i32 [[VAL]])
48 ; CHECK-NEXT:    br label [[LOOP]]
49 ; CHECK:       leave:
50 ; CHECK-NEXT:    ret void
52 entry:
53   %ptr.gep = getelementptr i8, ptr %ptr, i32 32
54   %ptr_is_null = icmp eq ptr %ptr, null
55   br i1 %ptr_is_null, label %leave, label %loop
58 loop:
59   call void @use(i32 0)
60   %val = load i32, ptr %ptr.gep, !invariant.load !{}
61   call void @use(i32 %val)
62   br label %loop
64 leave:
65   ret void
68 define void @f_2(ptr align 4 dereferenceable_or_null(1024) %ptr) {
69 ; CHECK-LABEL: @f_2(
70 ; CHECK-NEXT:  entry:
71 ; CHECK-NEXT:    [[PTR_GEP:%.*]] = getelementptr i8, ptr [[PTR:%.*]], i32 30
72 ; CHECK-NEXT:    [[PTR_IS_NULL:%.*]] = icmp eq ptr [[PTR]], null
73 ; CHECK-NEXT:    br i1 [[PTR_IS_NULL]], label [[LEAVE:%.*]], label [[LOOP_PREHEADER:%.*]]
74 ; CHECK:       loop.preheader:
75 ; CHECK-NEXT:    br label [[LOOP:%.*]]
76 ; CHECK:       loop:
77 ; CHECK-NEXT:    call void @use(i32 0)
78 ; CHECK-NEXT:    [[VAL:%.*]] = load i32, ptr [[PTR_GEP]], align 4, !invariant.load !0
79 ; CHECK-NEXT:    call void @use(i32 [[VAL]])
80 ; CHECK-NEXT:    br label [[LOOP]]
81 ; CHECK:       leave:
82 ; CHECK-NEXT:    ret void
85 entry:
86   ;; Can't hoist, since the alignment does not work out -- (<4 byte
87   ;; aligned> + 30) is not necessarily 4 byte aligned.
89   %ptr.gep = getelementptr i8, ptr %ptr, i32 30
90   %ptr_is_null = icmp eq ptr %ptr, null
91   br i1 %ptr_is_null, label %leave, label %loop
93 loop:
94   call void @use(i32 0)
95   %val = load i32, ptr %ptr.gep, !invariant.load !{}
96   call void @use(i32 %val)
97   br label %loop
99 leave:
100   ret void
103 define void @checkLaunder(ptr align 4 dereferenceable(1024) %p) nofree nosync {
104 ; CHECK-LABEL: @checkLaunder(
105 ; CHECK-NEXT:  entry:
106 ; CHECK-NEXT:    [[L:%.*]] = call ptr @llvm.launder.invariant.group.p0(ptr [[P:%.*]])
107 ; CHECK-NEXT:    [[VAL:%.*]] = load i8, ptr [[L]], align 1
108 ; CHECK-NEXT:    br label [[LOOP:%.*]]
109 ; CHECK:       loop:
110 ; CHECK-NEXT:    call void @use(i32 0)
111 ; CHECK-NEXT:    call void @use8(i8 [[VAL]])
112 ; CHECK-NEXT:    br label [[LOOP]]
115 entry:
116   %l = call ptr @llvm.launder.invariant.group.p0(ptr %p)
117   br label %loop
119 loop:
120   call void @use(i32 0)
121   %val = load i8, ptr %l, !invariant.load !{}
122   call void @use8(i8 %val)
123   br label %loop
126 declare ptr @llvm.launder.invariant.group.p0(ptr)
128 declare void @use8(i8)