1*a2223612SMichael Kruse // Check code generation
2*a2223612SMichael Kruse // RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 -emit-llvm %s -o - | FileCheck %s --check-prefix=IR
3*a2223612SMichael Kruse 
4*a2223612SMichael Kruse // Check same results after serialization round-trip
5*a2223612SMichael Kruse // RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 -emit-pch -o %t %s
6*a2223612SMichael Kruse // RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 -include-pch %t -emit-llvm %s -o - | FileCheck %s --check-prefix=IR
7*a2223612SMichael Kruse // expected-no-diagnostics
8*a2223612SMichael Kruse 
9*a2223612SMichael Kruse #ifndef HEADER
10*a2223612SMichael Kruse #define HEADER
11*a2223612SMichael Kruse 
12*a2223612SMichael Kruse // placeholder for loop body code.
13*a2223612SMichael Kruse extern "C" void body(...) {}
14*a2223612SMichael Kruse 
15*a2223612SMichael Kruse 
16*a2223612SMichael Kruse // IR-LABEL: @func(
17*a2223612SMichael Kruse // IR-NEXT:  [[ENTRY:.*]]:
18*a2223612SMichael Kruse // IR-NEXT:    %[[START_ADDR:.+]] = alloca i32, align 4
19*a2223612SMichael Kruse // IR-NEXT:    %[[END_ADDR:.+]] = alloca i32, align 4
20*a2223612SMichael Kruse // IR-NEXT:    %[[STEP_ADDR:.+]] = alloca i32, align 4
21*a2223612SMichael Kruse // IR-NEXT:    %[[I:.+]] = alloca i32, align 4
22*a2223612SMichael Kruse // IR-NEXT:    store i32 %[[START:.+]], i32* %[[START_ADDR]], align 4
23*a2223612SMichael Kruse // IR-NEXT:    store i32 %[[END:.+]], i32* %[[END_ADDR]], align 4
24*a2223612SMichael Kruse // IR-NEXT:    store i32 %[[STEP:.+]], i32* %[[STEP_ADDR]], align 4
25*a2223612SMichael Kruse // IR-NEXT:    %[[TMP0:.+]] = load i32, i32* %[[START_ADDR]], align 4
26*a2223612SMichael Kruse // IR-NEXT:    store i32 %[[TMP0]], i32* %[[I]], align 4
27*a2223612SMichael Kruse // IR-NEXT:    br label %[[FOR_COND:.+]]
28*a2223612SMichael Kruse // IR-EMPTY:
29*a2223612SMichael Kruse // IR-NEXT:  [[FOR_COND]]:
30*a2223612SMichael Kruse // IR-NEXT:    %[[TMP1:.+]] = load i32, i32* %[[I]], align 4
31*a2223612SMichael Kruse // IR-NEXT:    %[[TMP2:.+]] = load i32, i32* %[[END_ADDR]], align 4
32*a2223612SMichael Kruse // IR-NEXT:    %[[CMP:.+]] = icmp slt i32 %[[TMP1]], %[[TMP2]]
33*a2223612SMichael Kruse // IR-NEXT:    br i1 %[[CMP]], label %[[FOR_BODY:.+]], label %[[FOR_END:.+]]
34*a2223612SMichael Kruse // IR-EMPTY:
35*a2223612SMichael Kruse // IR-NEXT:  [[FOR_BODY]]:
36*a2223612SMichael Kruse // IR-NEXT:    %[[TMP3:.+]] = load i32, i32* %[[START_ADDR]], align 4
37*a2223612SMichael Kruse // IR-NEXT:    %[[TMP4:.+]] = load i32, i32* %[[END_ADDR]], align 4
38*a2223612SMichael Kruse // IR-NEXT:    %[[TMP5:.+]] = load i32, i32* %[[STEP_ADDR]], align 4
39*a2223612SMichael Kruse // IR-NEXT:    %[[TMP6:.+]] = load i32, i32* %[[I]], align 4
40*a2223612SMichael Kruse // IR-NEXT:    call void (...) @body(i32 %[[TMP3]], i32 %[[TMP4]], i32 %[[TMP5]], i32 %[[TMP6]])
41*a2223612SMichael Kruse // IR-NEXT:    br label %[[FOR_INC:.+]]
42*a2223612SMichael Kruse // IR-EMPTY:
43*a2223612SMichael Kruse // IR-NEXT:  [[FOR_INC]]:
44*a2223612SMichael Kruse // IR-NEXT:    %[[TMP7:.+]] = load i32, i32* %[[STEP_ADDR]], align 4
45*a2223612SMichael Kruse // IR-NEXT:    %[[TMP8:.+]] = load i32, i32* %[[I]], align 4
46*a2223612SMichael Kruse // IR-NEXT:    %[[ADD:.+]] = add nsw i32 %[[TMP8]], %[[TMP7]]
47*a2223612SMichael Kruse // IR-NEXT:    store i32 %[[ADD]], i32* %[[I]], align 4
48*a2223612SMichael Kruse // IR-NEXT:    br label %[[FOR_COND]], !llvm.loop ![[LOOP2:[0-9]+]]
49*a2223612SMichael Kruse // IR-EMPTY:
50*a2223612SMichael Kruse // IR-NEXT:  [[FOR_END]]:
51*a2223612SMichael Kruse // IR-NEXT:    ret void
52*a2223612SMichael Kruse // IR-NEXT:  }
53*a2223612SMichael Kruse extern "C" void func(int start, int end, int step) {
54*a2223612SMichael Kruse   #pragma omp unroll partial
55*a2223612SMichael Kruse   for (int i = start; i < end; i+=step)
56*a2223612SMichael Kruse     body(start, end, step, i);
57*a2223612SMichael Kruse }
58*a2223612SMichael Kruse 
59*a2223612SMichael Kruse #endif /* HEADER */
60*a2223612SMichael Kruse 
61*a2223612SMichael Kruse 
62*a2223612SMichael Kruse // IR: ![[LOOP2]] = distinct !{![[LOOP2]], ![[LOOPPROP3:[0-9]+]], ![[LOOPPROP4:[0-9]+]]}
63*a2223612SMichael Kruse // IR: ![[LOOPPROP3]] = !{!"llvm.loop.mustprogress"}
64*a2223612SMichael Kruse // IR: ![[LOOPPROP4]] = !{!"llvm.loop.unroll.enable"}
65