xref: /llvm-project/clang/test/OpenMP/generic_loop_codegen.cpp (revision fab49721b4ef0b5079194bc09528df78f38c32a8)
1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]"
2 // RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fopenmp %s
3 // RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fopenmp -emit-llvm %s -o - | FileCheck %s --check-prefix=IR
4 
5 // Check same results after serialization round-trip
6 // RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fopenmp -emit-pch -o %t %s
7 // RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fopenmp -include-pch %t -emit-llvm %s -o - | FileCheck %s --check-prefix=IR-PCH
8 
9 // expected-no-diagnostics
10 
11 #ifndef HEADER
12 #define HEADER
13 
14 void foo(int t) {
15 
16   int i, j, z;
17   #pragma omp loop collapse(2) reduction(+:z) lastprivate(j) bind(thread)
18   for (int i = 0; i<t; ++i)
19     for (j = 0; j<t; ++j)
20       z += i+j;
21 }
22 #endif
23 // IR-LABEL: define {{[^@]+}}@_Z3fooi
24 // IR-SAME: (i32 noundef [[T:%.*]]) #[[ATTR0:[0-9]+]] {
25 // IR-NEXT:  entry:
26 // IR-NEXT:    [[T_ADDR:%.*]] = alloca i32, align 4
27 // IR-NEXT:    [[I:%.*]] = alloca i32, align 4
28 // IR-NEXT:    [[J:%.*]] = alloca i32, align 4
29 // IR-NEXT:    [[Z:%.*]] = alloca i32, align 4
30 // IR-NEXT:    [[I1:%.*]] = alloca i32, align 4
31 // IR-NEXT:    store i32 [[T]], ptr [[T_ADDR]], align 4
32 // IR-NEXT:    store i32 0, ptr [[I1]], align 4
33 // IR-NEXT:    br label [[FOR_COND:%.*]]
34 // IR:       for.cond:
35 // IR-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I1]], align 4
36 // IR-NEXT:    [[TMP1:%.*]] = load i32, ptr [[T_ADDR]], align 4
37 // IR-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], [[TMP1]]
38 // IR-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END8:%.*]]
39 // IR:       for.body:
40 // IR-NEXT:    store i32 0, ptr [[J]], align 4
41 // IR-NEXT:    br label [[FOR_COND2:%.*]]
42 // IR:       for.cond2:
43 // IR-NEXT:    [[TMP2:%.*]] = load i32, ptr [[J]], align 4
44 // IR-NEXT:    [[TMP3:%.*]] = load i32, ptr [[T_ADDR]], align 4
45 // IR-NEXT:    [[CMP3:%.*]] = icmp slt i32 [[TMP2]], [[TMP3]]
46 // IR-NEXT:    br i1 [[CMP3]], label [[FOR_BODY4:%.*]], label [[FOR_END:%.*]]
47 // IR:       for.body4:
48 // IR-NEXT:    [[TMP4:%.*]] = load i32, ptr [[I1]], align 4
49 // IR-NEXT:    [[TMP5:%.*]] = load i32, ptr [[J]], align 4
50 // IR-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP4]], [[TMP5]]
51 // IR-NEXT:    [[TMP6:%.*]] = load i32, ptr [[Z]], align 4
52 // IR-NEXT:    [[ADD5:%.*]] = add nsw i32 [[TMP6]], [[ADD]]
53 // IR-NEXT:    store i32 [[ADD5]], ptr [[Z]], align 4
54 // IR-NEXT:    br label [[FOR_INC:%.*]]
55 // IR:       for.inc:
56 // IR-NEXT:    [[TMP7:%.*]] = load i32, ptr [[J]], align 4
57 // IR-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP7]], 1
58 // IR-NEXT:    store i32 [[INC]], ptr [[J]], align 4
59 // IR-NEXT:    br label [[FOR_COND2]], !llvm.loop [[LOOP3:![0-9]+]]
60 // IR:       for.end:
61 // IR-NEXT:    br label [[FOR_INC6:%.*]]
62 // IR:       for.inc6:
63 // IR-NEXT:    [[TMP8:%.*]] = load i32, ptr [[I1]], align 4
64 // IR-NEXT:    [[INC7:%.*]] = add nsw i32 [[TMP8]], 1
65 // IR-NEXT:    store i32 [[INC7]], ptr [[I1]], align 4
66 // IR-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP5:![0-9]+]]
67 // IR:       for.end8:
68 // IR-NEXT:    ret void
69 //
70 //
71 // IR-PCH-LABEL: define {{[^@]+}}@_Z3fooi
72 // IR-PCH-SAME: (i32 noundef [[T:%.*]]) #[[ATTR0:[0-9]+]] {
73 // IR-PCH-NEXT:  entry:
74 // IR-PCH-NEXT:    [[T_ADDR:%.*]] = alloca i32, align 4
75 // IR-PCH-NEXT:    [[I:%.*]] = alloca i32, align 4
76 // IR-PCH-NEXT:    [[J:%.*]] = alloca i32, align 4
77 // IR-PCH-NEXT:    [[Z:%.*]] = alloca i32, align 4
78 // IR-PCH-NEXT:    [[I1:%.*]] = alloca i32, align 4
79 // IR-PCH-NEXT:    store i32 [[T]], ptr [[T_ADDR]], align 4
80 // IR-PCH-NEXT:    store i32 0, ptr [[I1]], align 4
81 // IR-PCH-NEXT:    br label [[FOR_COND:%.*]]
82 // IR-PCH:       for.cond:
83 // IR-PCH-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I1]], align 4
84 // IR-PCH-NEXT:    [[TMP1:%.*]] = load i32, ptr [[T_ADDR]], align 4
85 // IR-PCH-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], [[TMP1]]
86 // IR-PCH-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END8:%.*]]
87 // IR-PCH:       for.body:
88 // IR-PCH-NEXT:    store i32 0, ptr [[J]], align 4
89 // IR-PCH-NEXT:    br label [[FOR_COND2:%.*]]
90 // IR-PCH:       for.cond2:
91 // IR-PCH-NEXT:    [[TMP2:%.*]] = load i32, ptr [[J]], align 4
92 // IR-PCH-NEXT:    [[TMP3:%.*]] = load i32, ptr [[T_ADDR]], align 4
93 // IR-PCH-NEXT:    [[CMP3:%.*]] = icmp slt i32 [[TMP2]], [[TMP3]]
94 // IR-PCH-NEXT:    br i1 [[CMP3]], label [[FOR_BODY4:%.*]], label [[FOR_END:%.*]]
95 // IR-PCH:       for.body4:
96 // IR-PCH-NEXT:    [[TMP4:%.*]] = load i32, ptr [[I1]], align 4
97 // IR-PCH-NEXT:    [[TMP5:%.*]] = load i32, ptr [[J]], align 4
98 // IR-PCH-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP4]], [[TMP5]]
99 // IR-PCH-NEXT:    [[TMP6:%.*]] = load i32, ptr [[Z]], align 4
100 // IR-PCH-NEXT:    [[ADD5:%.*]] = add nsw i32 [[TMP6]], [[ADD]]
101 // IR-PCH-NEXT:    store i32 [[ADD5]], ptr [[Z]], align 4
102 // IR-PCH-NEXT:    br label [[FOR_INC:%.*]]
103 // IR-PCH:       for.inc:
104 // IR-PCH-NEXT:    [[TMP7:%.*]] = load i32, ptr [[J]], align 4
105 // IR-PCH-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP7]], 1
106 // IR-PCH-NEXT:    store i32 [[INC]], ptr [[J]], align 4
107 // IR-PCH-NEXT:    br label [[FOR_COND2]], !llvm.loop [[LOOP3:![0-9]+]]
108 // IR-PCH:       for.end:
109 // IR-PCH-NEXT:    br label [[FOR_INC6:%.*]]
110 // IR-PCH:       for.inc6:
111 // IR-PCH-NEXT:    [[TMP8:%.*]] = load i32, ptr [[I1]], align 4
112 // IR-PCH-NEXT:    [[INC7:%.*]] = add nsw i32 [[TMP8]], 1
113 // IR-PCH-NEXT:    store i32 [[INC7]], ptr [[I1]], align 4
114 // IR-PCH-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP5:![0-9]+]]
115 // IR-PCH:       for.end8:
116 // IR-PCH-NEXT:    ret void
117 //
118