1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt  -aa-pipeline=basic-aa -passes='require<memoryssa>,gvn' -S -verify-memoryssa %s | FileCheck %s
3
4; REQUIRES: asserts
5
6declare void @use(i32) readnone
7
8define i32 @test(i32* %ptr.0, i32** %ptr.1, i1 %c) {
9; CHECK-LABEL: @test(
10; CHECK-NEXT:  entry:
11; CHECK-NEXT:    [[LV_0:%.*]] = load i32, i32* [[PTR_0:%.*]], align 8
12; CHECK-NEXT:    call void @use(i32 [[LV_0]])
13; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_THEN749:%.*]], label [[FOR_INC774:%.*]]
14; CHECK:       if.then749:
15; CHECK-NEXT:    [[LV_1:%.*]] = load i32*, i32** [[PTR_1:%.*]], align 8
16; CHECK-NEXT:    store i32 10, i32* [[LV_1]], align 4
17; CHECK-NEXT:    [[LV_2_PRE:%.*]] = load i32, i32* [[PTR_0]], align 8
18; CHECK-NEXT:    br label [[FOR_INC774]]
19; CHECK:       for.inc774:
20; CHECK-NEXT:    [[LV_2:%.*]] = phi i32 [ [[LV_2_PRE]], [[IF_THEN749]] ], [ [[LV_0]], [[ENTRY:%.*]] ]
21; CHECK-NEXT:    call void @use(i32 [[LV_2]])
22; CHECK-NEXT:    ret i32 1
23;
24entry:
25  br label %for.end435
26
27for.end435:
28  %lv.0 = load i32, i32* %ptr.0, align 8
29  call void @use(i32 %lv.0)
30  br label %if.end724
31
32if.end724:
33  br i1 %c, label %if.then749, label %for.inc774
34
35if.then749:
36  %lv.1 = load i32*, i32** %ptr.1, align 8
37  %arrayidx772 = getelementptr inbounds i32, i32* %lv.1, i64 0
38  store i32 10, i32* %arrayidx772, align 4
39  br label %for.inc774
40
41for.inc774:
42  br label %for.body830
43
44for.body830:
45  %lv.2 = load i32, i32* %ptr.0, align 8
46  call void @use(i32 %lv.2)
47  br label %for.body.i22
48
49for.body.i22:
50  ret i32 1
51}
52
53define i32 @test_volatile(i32* %ptr.0, i32** %ptr.1, i1 %c) {
54; CHECK-LABEL: @test_volatile(
55; CHECK-NEXT:  entry:
56; CHECK-NEXT:    [[LV_0:%.*]] = load volatile i32, i32* [[PTR_0:%.*]], align 8
57; CHECK-NEXT:    call void @use(i32 [[LV_0]])
58; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_THEN749:%.*]], label [[FOR_INC774:%.*]]
59; CHECK:       if.then749:
60; CHECK-NEXT:    [[LV_1:%.*]] = load volatile i32*, i32** [[PTR_1:%.*]], align 8
61; CHECK-NEXT:    store i32 10, i32* [[LV_1]], align 4
62; CHECK-NEXT:    br label [[FOR_INC774]]
63; CHECK:       for.inc774:
64; CHECK-NEXT:    [[LV_2:%.*]] = load volatile i32, i32* [[PTR_0]], align 8
65; CHECK-NEXT:    call void @use(i32 [[LV_2]])
66; CHECK-NEXT:    ret i32 1
67;
68entry:
69  br label %for.end435
70
71for.end435:
72  %lv.0 = load volatile i32, i32* %ptr.0, align 8
73  call void @use(i32 %lv.0)
74  br label %if.end724
75
76if.end724:
77  br i1 %c, label %if.then749, label %for.inc774
78
79if.then749:
80  %lv.1 = load volatile i32*, i32** %ptr.1, align 8
81  %arrayidx772 = getelementptr inbounds i32, i32* %lv.1, i64 0
82  store i32 10, i32* %arrayidx772, align 4
83  br label %for.inc774
84
85for.inc774:
86  br label %for.body830
87
88for.body830:
89  %lv.2 = load volatile i32, i32* %ptr.0, align 8
90  call void @use(i32 %lv.2)
91  br label %for.body.i22
92
93for.body.i22:
94  ret i32 1
95}
96
97define void @test_assume_false_to_store_undef_1(i32* %ptr) {
98; CHECK-LABEL: @test_assume_false_to_store_undef_1(
99; CHECK-NEXT:    store i32 10, i32* [[PTR:%.*]], align 4
100; CHECK-NEXT:    store i8 undef, i8* null, align 1
101; CHECK-NEXT:    call void @f()
102; CHECK-NEXT:    ret void
103;
104  store i32 10, i32* %ptr
105  %tobool = icmp ne i16 1, 0
106  %xor = xor i1 %tobool, true
107  call void @llvm.assume(i1 %xor)
108  call void @f()
109  ret void
110}
111
112define i32 @test_assume_false_to_store_undef_2(i32* %ptr, i32* %ptr.2) {
113; CHECK-LABEL: @test_assume_false_to_store_undef_2(
114; CHECK-NEXT:    store i32 10, i32* [[PTR:%.*]], align 4
115; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR_2:%.*]], align 4
116; CHECK-NEXT:    store i8 undef, i8* null, align 1
117; CHECK-NEXT:    call void @f()
118; CHECK-NEXT:    ret i32 [[LV]]
119;
120  store i32 10, i32* %ptr
121  %lv = load i32, i32* %ptr.2
122  %tobool = icmp ne i16 1, 0
123  %xor = xor i1 %tobool, true
124  call void @llvm.assume(i1 %xor)
125  call void @f()
126  ret i32 %lv
127}
128
129define i32 @test_assume_false_to_store_undef_3(i32* %ptr, i32* %ptr.2) {
130; CHECK-LABEL: @test_assume_false_to_store_undef_3(
131; CHECK-NEXT:    store i32 10, i32* [[PTR:%.*]], align 4
132; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR_2:%.*]], align 4
133; CHECK-NEXT:    store i8 undef, i8* null, align 1
134; CHECK-NEXT:    ret i32 [[LV]]
135;
136  store i32 10, i32* %ptr
137  %lv = load i32, i32* %ptr.2
138  %tobool = icmp ne i16 1, 0
139  %xor = xor i1 %tobool, true
140  call void @llvm.assume(i1 %xor)
141  ret i32 %lv
142}
143
144declare void @f()
145
146declare void @llvm.assume(i1 noundef) #0
147
148attributes #0 = { nofree nosync nounwind willreturn }
149