File: simplifycfg.ll

package info (click to toggle)
llvm-toolchain-17 1%3A17.0.6-22
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,799,624 kB
  • sloc: cpp: 6,428,607; ansic: 1,383,196; asm: 793,408; python: 223,504; objc: 75,364; f90: 60,502; lisp: 33,869; pascal: 15,282; sh: 9,684; perl: 7,453; ml: 4,937; awk: 3,523; makefile: 2,889; javascript: 2,149; xml: 888; fortran: 619; cs: 573
file content (130 lines) | stat: -rw-r--r-- 5,154 bytes parent folder | download | duplicates (12)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
; RUN: opt -O2 -S < %s | FileCheck %s
;
; This test tries to ensure that simplifycfg hoisting common instructions
; of then/else branch indeed happens. BPF target has added an IR pass
; before loop optimizations as Commit 1d51dc38d89b
; ([SimplifyCFG][LoopRotate] SimplifyCFG: disable common instruction
;  hoisting by default, enable late in pipeline)
; disabled common instruction hoisting. Due to optimization triggered
; code changes, later SimplifyCFG may not be able to perform optimization
; even common inst hoisting is enabled.
;
; Source:
;   typedef struct {
;     void *f_back;
;   } FrameData;
;   extern int get_data(void *, void *);
;   extern void get_frame_ptr(void *);
;   int test() {
;     void *frame_ptr;
;     FrameData frame;
;
;     get_frame_ptr(&frame_ptr);
;
;     #pragma nounroll
;     for (int i = 0; i < 6; i++) {
;       if (frame_ptr && get_data(frame_ptr, &frame)) {
;         frame_ptr = frame.f_back;
;       }
;     }
;     return frame_ptr == 0;
;   }
; Compilation flag:
;   clang -target bpf -O2 -Xclang -disable-llvm-passes -S -emit-llvm t.c -o t.ll

target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
target triple = "bpf"

%struct.FrameData = type { ptr }

; Function Attrs: nounwind
define dso_local i32 @test() #0 {
entry:
  %frame_ptr = alloca ptr, align 8
  %frame = alloca %struct.FrameData, align 8
  %i = alloca i32, align 4
  call void @llvm.lifetime.start.p0(i64 8, ptr %frame_ptr) #3
  call void @llvm.lifetime.start.p0(i64 8, ptr %frame) #3
  call void @get_frame_ptr(ptr %frame_ptr)
  call void @llvm.lifetime.start.p0(i64 4, ptr %i) #3
  store i32 0, ptr %i, align 4, !tbaa !2
  br label %for.cond

; CHECK-LABEL:    entry
; CHECK:          %[[PTR:[0-9]+]] = load ptr, ptr %frame_ptr, align 8
; CHECK:          %{{[0-9a-z.]+}} = icmp eq ptr %[[PTR]], null
; CHECK:          br label

for.cond:                                         ; preds = %for.inc, %entry
  %0 = load i32, ptr %i, align 4, !tbaa !2
  %cmp = icmp slt i32 %0, 6
  br i1 %cmp, label %for.body, label %for.cond.cleanup

for.cond.cleanup:                                 ; preds = %for.cond
  call void @llvm.lifetime.end.p0(i64 4, ptr %i) #3
  br label %for.end

for.body:                                         ; preds = %for.cond
  %1 = load ptr, ptr %frame_ptr, align 8, !tbaa !6
  %tobool = icmp ne ptr %1, null
  br i1 %tobool, label %land.lhs.true, label %if.end

land.lhs.true:                                    ; preds = %for.body
  %2 = load ptr, ptr %frame_ptr, align 8, !tbaa !6
  %call = call i32 @get_data(ptr %2, ptr %frame)
  %tobool1 = icmp ne i32 %call, 0
  br i1 %tobool1, label %if.then, label %if.end

if.then:                                          ; preds = %land.lhs.true
  %3 = load ptr, ptr %frame, align 8, !tbaa !8
  store ptr %3, ptr %frame_ptr, align 8, !tbaa !6
  br label %if.end

if.end:                                           ; preds = %if.then, %land.lhs.true, %for.body
  br label %for.inc

for.inc:                                          ; preds = %if.end
  %4 = load i32, ptr %i, align 4, !tbaa !2
  %inc = add nsw i32 %4, 1
  store i32 %inc, ptr %i, align 4, !tbaa !2
  br label %for.cond, !llvm.loop !10

for.end:                                          ; preds = %for.cond.cleanup
  %5 = load ptr, ptr %frame_ptr, align 8, !tbaa !6
  %cmp2 = icmp eq ptr %5, null
  %conv = zext i1 %cmp2 to i32
  call void @llvm.lifetime.end.p0(i64 8, ptr %frame) #3
  call void @llvm.lifetime.end.p0(i64 8, ptr %frame_ptr) #3
  ret i32 %conv
}

; Function Attrs: argmemonly nounwind willreturn
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1

declare dso_local void @get_frame_ptr(ptr) #2

declare dso_local i32 @get_data(ptr, ptr) #2

; Function Attrs: argmemonly nounwind willreturn
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1

attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { argmemonly nounwind willreturn }
attributes #2 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #3 = { nounwind }

!llvm.module.flags = !{!0}
!llvm.ident = !{!1}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 12.0.0 (https://github.com/llvm/llvm-project.git 1b3c1c543269da36ae41ab84f646cf98d2e5b1e5)"}
!2 = !{!3, !3, i64 0}
!3 = !{!"int", !4, i64 0}
!4 = !{!"omnipotent char", !5, i64 0}
!5 = !{!"Simple C/C++ TBAA"}
!6 = !{!7, !7, i64 0}
!7 = !{!"any pointer", !4, i64 0}
!8 = !{!9, !7, i64 0}
!9 = !{!"", !7, i64 0}
!10 = distinct !{!10, !11}
!11 = !{!"llvm.loop.unroll.disable"}