[Coverage] MCDC: Move findIndependencePairs deferred into MCDCRecord (#121188)
[llvm-project.git] / llvm / test / Analysis / ValueTracking / assume.ll
blob4c4b46c4199686830abba38a9505b134e55851d9
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 define i32 @assume_add(i32 %a, i32 %b) {
5 ; CHECK-LABEL: @assume_add(
6 ; CHECK-NEXT:    [[T1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
7 ; CHECK-NEXT:    [[LAST_TWO_DIGITS:%.*]] = and i32 [[T1]], 3
8 ; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[LAST_TWO_DIGITS]], 0
9 ; CHECK-NEXT:    call void @llvm.assume(i1 [[T2]])
10 ; CHECK-NEXT:    [[T3:%.*]] = or disjoint i32 [[T1]], 3
11 ; CHECK-NEXT:    ret i32 [[T3]]
13   %t1 = add i32 %a, %b
14   %last_two_digits = and i32 %t1, 3
15   %t2 = icmp eq i32 %last_two_digits, 0
16   call void @llvm.assume(i1 %t2)
17   %t3 = add i32 %t1, 3
18   ret i32 %t3
22 define void @assume_not() {
23 ; CHECK-LABEL: @assume_not(
24 ; CHECK-NEXT:  entry-block:
25 ; CHECK-NEXT:    [[TMP0:%.*]] = call i1 @get_val()
26 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[TMP0]], true
27 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP1]])
28 ; CHECK-NEXT:    ret void
30 entry-block:
31   %0 = call i1 @get_val()
32   %1 = xor i1 %0, true
33   call void @llvm.assume(i1 %1)
34   ret void
37 declare i1 @get_val()
38 declare void @llvm.assume(i1)
40 define dso_local i1 @test1(ptr readonly %0) {
41 ; CHECK-LABEL: @test1(
42 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[TMP0:%.*]]) ]
43 ; CHECK-NEXT:    ret i1 false
45   call void @llvm.assume(i1 true) ["nonnull"(ptr %0)]
46   %2 = icmp eq ptr %0, null
47   ret i1 %2
50 define dso_local i1 @test2(ptr readonly %0) {
51 ; CHECK-LABEL: @test2(
52 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[TMP0:%.*]]) ]
53 ; CHECK-NEXT:    ret i1 false
55   %2 = icmp eq ptr %0, null
56   call void @llvm.assume(i1 true) ["nonnull"(ptr %0)]
57   ret i1 %2
60 define dso_local i32 @test4(ptr readonly %0, i1 %cond) {
61 ; CHECK-LABEL: @test4(
62 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[TMP0:%.*]], i32 4) ]
63 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[A:%.*]], label [[B:%.*]]
64 ; CHECK:       B:
65 ; CHECK-NEXT:    br label [[A]]
66 ; CHECK:       A:
67 ; CHECK-NEXT:    br i1 false, label [[TMP4:%.*]], label [[TMP2:%.*]]
68 ; CHECK:       2:
69 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
70 ; CHECK-NEXT:    br label [[TMP4]]
71 ; CHECK:       4:
72 ; CHECK-NEXT:    [[TMP5:%.*]] = phi i32 [ [[TMP3]], [[TMP2]] ], [ poison, [[A]] ]
73 ; CHECK-NEXT:    ret i32 [[TMP5]]
75   call void @llvm.assume(i1 true) ["dereferenceable"(ptr %0, i32 4)]
76   br i1 %cond, label %A, label %B
79   br label %A
82   %2 = icmp eq ptr %0, null
83   br i1 %2, label %5, label %3
85 3:                                                ; preds = %1
86   %4 = load i32, ptr %0, align 4
87   br label %5
89 5:                                                ; preds = %1, %3
90   %6 = phi i32 [ %4, %3 ], [ 0, %A ]
91   ret i32 %6
94 define dso_local i32 @test4a(ptr readonly %0, i1 %cond) {
95 ; CHECK-LABEL: @test4a(
96 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[TMP0:%.*]], i32 4), "align"(ptr [[TMP0]], i32 8) ]
97 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[A:%.*]], label [[B:%.*]]
98 ; CHECK:       B:
99 ; CHECK-NEXT:    br label [[A]]
100 ; CHECK:       A:
101 ; CHECK-NEXT:    br i1 false, label [[TMP4:%.*]], label [[TMP2:%.*]]
102 ; CHECK:       2:
103 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
104 ; CHECK-NEXT:    br label [[TMP4]]
105 ; CHECK:       4:
106 ; CHECK-NEXT:    [[TMP5:%.*]] = phi i32 [ [[TMP3]], [[TMP2]] ], [ poison, [[A]] ]
107 ; CHECK-NEXT:    ret i32 [[TMP5]]
109   call void @llvm.assume(i1 true) ["dereferenceable"(ptr %0, i32 4), "align"(ptr %0, i32 8)]
110   br i1 %cond, label %A, label %B
113   br label %A
116   %2 = icmp eq ptr %0, null
117   br i1 %2, label %5, label %3
119 3:                                                ; preds = %1
120   %4 = load i32, ptr %0, align 4
121   br label %5
123 5:                                                ; preds = %1, %3
124   %6 = phi i32 [ %4, %3 ], [ 0, %A ]
125   ret i32 %6
128 define dso_local i32 @test4b(ptr readonly %0, i1 %cond) null_pointer_is_valid {
129 ; CHECK-LABEL: @test4b(
130 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[TMP0:%.*]], i32 4) ]
131 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[A:%.*]], label [[B:%.*]]
132 ; CHECK:       B:
133 ; CHECK-NEXT:    br label [[A]]
134 ; CHECK:       A:
135 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq ptr [[TMP0]], null
136 ; CHECK-NEXT:    br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]]
137 ; CHECK:       3:
138 ; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[TMP0]], align 4
139 ; CHECK-NEXT:    br label [[TMP5]]
140 ; CHECK:       5:
141 ; CHECK-NEXT:    [[TMP6:%.*]] = phi i32 [ [[TMP4]], [[TMP3]] ], [ 0, [[A]] ]
142 ; CHECK-NEXT:    ret i32 [[TMP6]]
144   call void @llvm.assume(i1 true) ["dereferenceable"(ptr %0, i32 4)]
145   br i1 %cond, label %A, label %B
148   br label %A
151   %2 = icmp eq ptr %0, null
152   br i1 %2, label %5, label %3
154 3:                                                ; preds = %1
155   %4 = load i32, ptr %0, align 4
156   br label %5
158 5:                                                ; preds = %1, %3
159   %6 = phi i32 [ %4, %3 ], [ 0, %A ]
160   ret i32 %6