pragma-loop-safety.cpp revision b6d6993e6e6d3daf4d9876794254d20a134e37c2
1// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s 2 3// Verify assume_safety vectorization is recognized. 4void vectorize_test(int *List, int Length) { 5// CHECK: define {{.*}} @_Z14vectorize_testPii 6// CHECK: [[LOAD1_IV:.+]] = load i32, i32* [[IV1:[^,]+]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID:[0-9]+]] 7// CHECK-NEXT: [[LOAD1_LEN:.+]] = load i32, i32* [[LEN1:.+]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]] 8// CHECK-NEXT: [[CMP1:.+]] = icmp slt i32[[LOAD1_IV]],[[LOAD1_LEN]] 9// CHECK-NEXT: br i1[[CMP1]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]], !llvm.loop ![[LOOP1_HINTS:[0-9]+]] 10#pragma clang loop vectorize(assume_safety) 11 for (int i = 0; i < Length; i++) { 12 // CHECK: [[LOOP1_BODY]] 13 // CHECK-NEXT: [[RHIV1:.+]] = load i32, i32* [[IV1]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]] 14 // CHECK-NEXT: [[CALC1:.+]] = mul nsw i32[[RHIV1]], 2 15 // CHECK-NEXT: [[SIV1:.+]] = load i32, i32* [[IV1]]{{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]] 16 // CHECK-NEXT: [[INDEX1:.+]] = sext i32[[SIV1]] to i64 17 // CHECK-NEXT: [[ARRAY1:.+]] = load i32*, i32** [[LIST1:.*]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]] 18 // CHECK-NEXT: [[PTR1:.+]] = getelementptr inbounds i32, i32*[[ARRAY1]], i64[[INDEX1]] 19 // CHECK-NEXT: store i32[[CALC1]], i32*[[PTR1]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]] 20 List[i] = i * 2; 21 } 22 // CHECK: [[LOOP1_END]] 23} 24 25// Verify assume_safety interleaving is recognized. 26void interleave_test(int *List, int Length) { 27// CHECK: define {{.*}} @_Z15interleave_testPii 28// CHECK: [[LOAD2_IV:.+]] = load i32, i32* [[IV2:[^,]+]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID:[0-9]+]] 29// CHECK-NEXT: [[LOAD2_LEN:.+]] = load i32, i32* [[LEN2:.+]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]] 30// CHECK-NEXT: [[CMP2:.+]] = icmp slt i32[[LOAD2_IV]],[[LOAD2_LEN]] 31// CHECK-NEXT: br i1[[CMP2]], label %[[LOOP2_BODY:[^,]+]], label %[[LOOP2_END:[^,]+]], !llvm.loop ![[LOOP2_HINTS:[0-9]+]] 32#pragma clang loop interleave(assume_safety) 33 for (int i = 0; i < Length; i++) { 34 // CHECK: [[LOOP2_BODY]] 35 // CHECK-NEXT: [[RHIV2:.+]] = load i32, i32* [[IV2]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]] 36 // CHECK-NEXT: [[CALC2:.+]] = mul nsw i32[[RHIV2]], 2 37 // CHECK-NEXT: [[SIV2:.+]] = load i32, i32* [[IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]] 38 // CHECK-NEXT: [[INDEX2:.+]] = sext i32[[SIV2]] to i64 39 // CHECK-NEXT: [[ARRAY2:.+]] = load i32*, i32** [[LIST2:.*]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]] 40 // CHECK-NEXT: [[PTR2:.+]] = getelementptr inbounds i32, i32*[[ARRAY2]], i64[[INDEX2]] 41 // CHECK-NEXT: store i32[[CALC2]], i32*[[PTR2]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]] 42 List[i] = i * 2; 43 } 44 // CHECK: [[LOOP2_END]] 45} 46 47// CHECK: ![[LOOP1_HINTS]] = distinct !{![[LOOP1_HINTS]], ![[INTENABLE_1:.*]]} 48// CHCCK: ![[INTENABLE_1]] = !{!"llvm.loop.vectorize.enable", i1 true} 49// CHECK: ![[LOOP2_HINTS]] = distinct !{![[LOOP2_HINTS]], ![[INTENABLE_1:.*]]} 50