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
|
// 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[.].+[.|,]"
// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fopenmp %s
// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fopenmp -emit-llvm %s -o - | FileCheck %s --check-prefix=IR
// Check same results after serialization round-trip
// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fopenmp -emit-pch -o %t %s
// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fopenmp -include-pch %t -emit-llvm %s -o - | FileCheck %s --check-prefix=IR-PCH
// expected-no-diagnostics
#ifndef HEADER
#define HEADER
void foo(int t) {
int i, j, z;
#pragma omp loop collapse(2) reduction(+:z) lastprivate(j) bind(thread)
for (int i = 0; i<t; ++i)
for (j = 0; j<t; ++j)
z += i+j;
}
#endif
// IR-LABEL: define {{[^@]+}}@_Z3fooi
// IR-SAME: (i32 noundef [[T:%.*]]) #[[ATTR0:[0-9]+]] {
// IR-NEXT: entry:
// IR-NEXT: [[T_ADDR:%.*]] = alloca i32, align 4
// IR-NEXT: [[I:%.*]] = alloca i32, align 4
// IR-NEXT: [[J:%.*]] = alloca i32, align 4
// IR-NEXT: [[Z:%.*]] = alloca i32, align 4
// IR-NEXT: [[I1:%.*]] = alloca i32, align 4
// IR-NEXT: store i32 [[T]], ptr [[T_ADDR]], align 4
// IR-NEXT: store i32 0, ptr [[I1]], align 4
// IR-NEXT: br label [[FOR_COND:%.*]]
// IR: for.cond:
// IR-NEXT: [[TMP0:%.*]] = load i32, ptr [[I1]], align 4
// IR-NEXT: [[TMP1:%.*]] = load i32, ptr [[T_ADDR]], align 4
// IR-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], [[TMP1]]
// IR-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END8:%.*]]
// IR: for.body:
// IR-NEXT: store i32 0, ptr [[J]], align 4
// IR-NEXT: br label [[FOR_COND2:%.*]]
// IR: for.cond2:
// IR-NEXT: [[TMP2:%.*]] = load i32, ptr [[J]], align 4
// IR-NEXT: [[TMP3:%.*]] = load i32, ptr [[T_ADDR]], align 4
// IR-NEXT: [[CMP3:%.*]] = icmp slt i32 [[TMP2]], [[TMP3]]
// IR-NEXT: br i1 [[CMP3]], label [[FOR_BODY4:%.*]], label [[FOR_END:%.*]]
// IR: for.body4:
// IR-NEXT: [[TMP4:%.*]] = load i32, ptr [[I1]], align 4
// IR-NEXT: [[TMP5:%.*]] = load i32, ptr [[J]], align 4
// IR-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP4]], [[TMP5]]
// IR-NEXT: [[TMP6:%.*]] = load i32, ptr [[Z]], align 4
// IR-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP6]], [[ADD]]
// IR-NEXT: store i32 [[ADD5]], ptr [[Z]], align 4
// IR-NEXT: br label [[FOR_INC:%.*]]
// IR: for.inc:
// IR-NEXT: [[TMP7:%.*]] = load i32, ptr [[J]], align 4
// IR-NEXT: [[INC:%.*]] = add nsw i32 [[TMP7]], 1
// IR-NEXT: store i32 [[INC]], ptr [[J]], align 4
// IR-NEXT: br label [[FOR_COND2]], !llvm.loop [[LOOP3:![0-9]+]]
// IR: for.end:
// IR-NEXT: br label [[FOR_INC6:%.*]]
// IR: for.inc6:
// IR-NEXT: [[TMP8:%.*]] = load i32, ptr [[I1]], align 4
// IR-NEXT: [[INC7:%.*]] = add nsw i32 [[TMP8]], 1
// IR-NEXT: store i32 [[INC7]], ptr [[I1]], align 4
// IR-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP5:![0-9]+]]
// IR: for.end8:
// IR-NEXT: ret void
//
//
// IR-PCH-LABEL: define {{[^@]+}}@_Z3fooi
// IR-PCH-SAME: (i32 noundef [[T:%.*]]) #[[ATTR0:[0-9]+]] {
// IR-PCH-NEXT: entry:
// IR-PCH-NEXT: [[T_ADDR:%.*]] = alloca i32, align 4
// IR-PCH-NEXT: [[I:%.*]] = alloca i32, align 4
// IR-PCH-NEXT: [[J:%.*]] = alloca i32, align 4
// IR-PCH-NEXT: [[Z:%.*]] = alloca i32, align 4
// IR-PCH-NEXT: [[I1:%.*]] = alloca i32, align 4
// IR-PCH-NEXT: store i32 [[T]], ptr [[T_ADDR]], align 4
// IR-PCH-NEXT: store i32 0, ptr [[I1]], align 4
// IR-PCH-NEXT: br label [[FOR_COND:%.*]]
// IR-PCH: for.cond:
// IR-PCH-NEXT: [[TMP0:%.*]] = load i32, ptr [[I1]], align 4
// IR-PCH-NEXT: [[TMP1:%.*]] = load i32, ptr [[T_ADDR]], align 4
// IR-PCH-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], [[TMP1]]
// IR-PCH-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END8:%.*]]
// IR-PCH: for.body:
// IR-PCH-NEXT: store i32 0, ptr [[J]], align 4
// IR-PCH-NEXT: br label [[FOR_COND2:%.*]]
// IR-PCH: for.cond2:
// IR-PCH-NEXT: [[TMP2:%.*]] = load i32, ptr [[J]], align 4
// IR-PCH-NEXT: [[TMP3:%.*]] = load i32, ptr [[T_ADDR]], align 4
// IR-PCH-NEXT: [[CMP3:%.*]] = icmp slt i32 [[TMP2]], [[TMP3]]
// IR-PCH-NEXT: br i1 [[CMP3]], label [[FOR_BODY4:%.*]], label [[FOR_END:%.*]]
// IR-PCH: for.body4:
// IR-PCH-NEXT: [[TMP4:%.*]] = load i32, ptr [[I1]], align 4
// IR-PCH-NEXT: [[TMP5:%.*]] = load i32, ptr [[J]], align 4
// IR-PCH-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP4]], [[TMP5]]
// IR-PCH-NEXT: [[TMP6:%.*]] = load i32, ptr [[Z]], align 4
// IR-PCH-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP6]], [[ADD]]
// IR-PCH-NEXT: store i32 [[ADD5]], ptr [[Z]], align 4
// IR-PCH-NEXT: br label [[FOR_INC:%.*]]
// IR-PCH: for.inc:
// IR-PCH-NEXT: [[TMP7:%.*]] = load i32, ptr [[J]], align 4
// IR-PCH-NEXT: [[INC:%.*]] = add nsw i32 [[TMP7]], 1
// IR-PCH-NEXT: store i32 [[INC]], ptr [[J]], align 4
// IR-PCH-NEXT: br label [[FOR_COND2]], !llvm.loop [[LOOP3:![0-9]+]]
// IR-PCH: for.end:
// IR-PCH-NEXT: br label [[FOR_INC6:%.*]]
// IR-PCH: for.inc6:
// IR-PCH-NEXT: [[TMP8:%.*]] = load i32, ptr [[I1]], align 4
// IR-PCH-NEXT: [[INC7:%.*]] = add nsw i32 [[TMP8]], 1
// IR-PCH-NEXT: store i32 [[INC7]], ptr [[I1]], align 4
// IR-PCH-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP5:![0-9]+]]
// IR-PCH: for.end8:
// IR-PCH-NEXT: ret void
//
|