1 | // RUN: %clang_cc1 -x cl -O1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -check-prefix=OPT |
2 | // RUN: %clang_cc1 -x cl -O0 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -check-prefix=NOOPT |
3 | |
4 | // OpenCL essentially reduces all shift amounts to the last word-size |
5 | // bits before evaluating. Test this both for variables and constants |
6 | // evaluated in the front-end. |
7 | |
8 | // OPT: @gtest1 = local_unnamed_addr constant i64 2147483648 |
9 | __constant const unsigned long gtest1 = 1UL << 31; |
10 | |
11 | // NOOPT: @negativeShift32 |
12 | int negativeShift32(int a,int b) { |
13 | // NOOPT: %array0 = alloca [256 x i8] |
14 | char array0[((int)1)<<40]; |
15 | // NOOPT: %array1 = alloca [256 x i8] |
16 | char array1[((int)1)<<(-24)]; |
17 | |
18 | // NOOPT: ret i32 65536 |
19 | return ((int)1)<<(-16); |
20 | } |
21 | |
22 | //OPT: @positiveShift32 |
23 | int positiveShift32(int a,int b) { |
24 | //OPT: [[M32:%.+]] = and i32 %b, 31 |
25 | //OPT-NEXT: [[C32:%.+]] = shl i32 %a, [[M32]] |
26 | int c = a<<b; |
27 | int d = ((int)1)<<33; |
28 | //OPT-NEXT: [[E32:%.+]] = add nsw i32 [[C32]], 2 |
29 | int e = c + d; |
30 | //OPT-NEXT: ret i32 [[E32]] |
31 | return e; |
32 | } |
33 | |
34 | //OPT: @positiveShift64 |
35 | long positiveShift64(long a,long b) { |
36 | //OPT: [[M64:%.+]] = and i64 %b, 63 |
37 | //OPT-NEXT: [[C64:%.+]] = ashr i64 %a, [[M64]] |
38 | long c = a>>b; |
39 | long d = ((long)8)>>65; |
40 | //OPT-NEXT: [[E64:%.+]] = add nsw i64 [[C64]], 4 |
41 | long e = c + d; |
42 | //OPT-NEXT: ret i64 [[E64]] |
43 | return e; |
44 | } |
45 | |
46 | typedef __attribute__((ext_vector_type(4))) int int4; |
47 | |
48 | //OPT: @vectorVectorTest |
49 | int4 vectorVectorTest(int4 a,int4 b) { |
50 | //OPT: [[VM:%.+]] = and <4 x i32> %b, <i32 31, i32 31, i32 31, i32 31> |
51 | //OPT-NEXT: [[VC:%.+]] = shl <4 x i32> %a, [[VM]] |
52 | int4 c = a << b; |
53 | //OPT-NEXT: [[VF:%.+]] = add <4 x i32> [[VC]], <i32 2, i32 4, i32 16, i32 8> |
54 | int4 d = {1, 1, 1, 1}; |
55 | int4 e = {33, 34, -28, -29}; |
56 | int4 f = c + (d << e); |
57 | //OPT-NEXT: ret <4 x i32> [[VF]] |
58 | return f; |
59 | } |
60 | |
61 | //NOOPT-LABEL: @vectorScalarTest |
62 | int4 vectorScalarTest(int4 a,int b) { |
63 | //NOOPT: [[SP0:%.+]] = insertelement <4 x i32> undef |
64 | //NOOPT: [[SP1:%.+]] = shufflevector <4 x i32> [[SP0]], <4 x i32> undef, <4 x i32> zeroinitializer |
65 | //NOOPT: [[VSM:%.+]] = and <4 x i32> [[SP1]], <i32 31, i32 31, i32 31, i32 31> |
66 | //NOOPT: [[VSC:%.+]] = shl <4 x i32> [[VSS:%.+]], [[VSM]] |
67 | int4 c = a << b; |
68 | //NOOPT: [[VSF:%.+]] = shl <4 x i32> [[VSC1:%.+]], <i32 2, i32 2, i32 2, i32 2> |
69 | //NOOPT: [[VSA:%.+]] = add <4 x i32> [[VSC2:%.+]], [[VSF]] |
70 | int4 d = {1, 1, 1, 1}; |
71 | int4 f = c + (d << 34); |
72 | //NOOPT: ret <4 x i32> |
73 | return f; |
74 | } |
75 | |