]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/Transforms/JumpThreading/assume.ll
Vendor import of llvm trunk r303571:
[FreeBSD/FreeBSD.git] / test / Transforms / JumpThreading / assume.ll
1 ; RUN: opt -S -jump-threading -dce < %s | FileCheck %s
2 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
3 target triple = "x86_64-unknown-linux-gnu"
4
5 ; Function Attrs: nounwind uwtable
6 define i32 @test1(i32 %a, i32 %b) #0 {
7 entry:
8   %cmp = icmp sgt i32 %a, 5
9   tail call void @llvm.assume(i1 %cmp)
10   %cmp1 = icmp sgt i32 %b, 1234
11   br i1 %cmp1, label %if.then, label %if.else
12
13 ; CHECK-LABEL: @test1
14 ; CHECK: icmp sgt i32 %a, 5
15 ; CHECK: call void @llvm.assume
16 ; CHECK-NOT: icmp sgt i32 %a, 3
17 ; CHECK: ret i32
18
19 if.then:                                          ; preds = %entry
20   %cmp2 = icmp sgt i32 %a, 3
21   br i1 %cmp2, label %if.then3, label %return
22
23 if.then3:                                         ; preds = %if.then
24   tail call void (...) @bar() #1
25   br label %return
26
27 if.else:                                          ; preds = %entry
28   tail call void (...) @car() #1
29   br label %return
30
31 return:                                           ; preds = %if.else, %if.then, %if.then3
32   %retval.0 = phi i32 [ 1, %if.then3 ], [ 0, %if.then ], [ 0, %if.else ]
33   ret i32 %retval.0
34 }
35
36 define i32 @test2(i32 %a) #0 {
37 entry:
38   %cmp = icmp sgt i32 %a, 5
39   tail call void @llvm.assume(i1 %cmp)
40   %cmp1 = icmp sgt i32 %a, 3
41   br i1 %cmp1, label %if.then, label %return
42
43 ; CHECK-LABEL: @test2
44 ; CHECK: icmp sgt i32 %a, 5
45 ; CHECK: tail call void @llvm.assume
46 ; CHECK: tail call void (...) @bar()
47 ; CHECK: ret i32 1
48
49
50 if.then:                                          ; preds = %entry
51   tail call void (...) @bar() #1
52   br label %return
53
54 return:                                           ; preds = %entry, %if.then
55   %retval.0 = phi i32 [ 1, %if.then ], [ 0, %entry ]
56   ret i32 %retval.0
57 }
58
59 @g = external global i32
60
61 ; Check that we do prove a fact using an assume within the block.
62 ; FIXME: We can fold the assume based on the semantics of assume.
63 ; CHECK-LABEL: @can_fold_assume
64 ; CHECK: %notnull = icmp ne i32* %array, null
65 ; CHECK-NEXT: call void @llvm.assume(i1 %notnull)
66 ; CHECK-NEXT: ret void
67 define void @can_fold_assume(i32* %array) {
68   %notnull = icmp ne i32* %array, null
69   call void @llvm.assume(i1 %notnull)
70   br i1 %notnull, label %normal, label %error
71
72 normal:
73   ret void
74
75 error:
76   store atomic i32 0, i32* @g unordered, align 4
77   ret void
78 }
79
80 declare void @f(i1)
81 declare void @exit()
82 ; We can fold the assume but not the uses before the assume.
83 define void @dont_fold_incorrectly(i32* %array) {
84 ; CHECK-LABEL:@dont_fold_incorrectly
85 ; CHECK: @f(i1 %notnull)
86 ; CHECK-NEXT: exit()
87 ; CHECK-NEXT: assume(i1 %notnull)
88 ; CHECK-NEXT: ret void
89   %notnull = icmp ne i32* %array, null
90   call void @f(i1 %notnull)
91   call void @exit()
92   call void @llvm.assume(i1 %notnull)
93   br i1 %notnull, label %normal, label %error
94
95 normal:
96   ret void
97
98 error:
99   store atomic i32 0, i32* @g unordered, align 4
100   ret void
101 }
102
103 ; Function Attrs: nounwind
104 declare void @llvm.assume(i1) #1
105
106 declare void @bar(...)
107
108 declare void @car(...)
109
110 attributes #0 = { nounwind uwtable }
111 attributes #1 = { nounwind }
112