Scalar shifts in the OpenCL specification (as of v. 1.2) are defined to be
with respect to the lower "left-hand-side bitwidth" bits, even when negative);
see OpenCL spec 6.3j. This patch both implements this behaviour in the code
generator and "constant folding" bits of Sema, and also prevents tests
to detect undefinedness in terms of the weaker C99 or C++ specifications
from being applied. 


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@171755 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CodeGen/catch-undef-behavior.c b/test/CodeGen/catch-undef-behavior.c
index d0b6d19..9170666 100644
--- a/test/CodeGen/catch-undef-behavior.c
+++ b/test/CodeGen/catch-undef-behavior.c
@@ -99,7 +99,7 @@
 
 // CHECK: @rsh_inbounds
 int rsh_inbounds(int a, int b) {
-  // CHECK:      %[[INBOUNDS:.*]] = icmp ult i32 %[[RHS:.*]], 32
+  // CHECK:      %[[INBOUNDS:.*]] = icmp ule i32 %[[RHS:.*]], 31
   // CHECK:      br i1 %[[INBOUNDS]]
 
   // CHECK:      %[[ARG1:.*]] = zext
diff --git a/test/CodeGenOpenCL/shifts.cl b/test/CodeGenOpenCL/shifts.cl
new file mode 100644
index 0000000..b84ec1e
--- /dev/null
+++ b/test/CodeGenOpenCL/shifts.cl
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -x cl -O1 -emit-llvm  %s -o - -triple x86_64-linux-gnu | FileCheck %s
+// OpenCL essentially reduces all shift amounts to the last word-size bits before evaluating.
+// Test this both for variables and constants evaluated in the front-end.
+
+
+//CHECK: @positiveShift32
+int positiveShift32(int a,int b) {
+  //CHECK: %shl.mask = and i32 %b, 31
+  //CHECK-NEXT: %shl = shl i32 %a, %shl.mask
+  int c = a<<b;
+  int d = ((int)1)<<33;
+  //CHECK-NEXT: %add = add nsw i32 %shl, 2
+  int e = c + d;
+  //CHECK-NEXT: ret i32 %add
+  return e;
+}
+
+//CHECK: @positiveShift64
+long positiveShift64(long a,long b) {
+  //CHECK: %shr.mask = and i64 %b, 63
+  //CHECK-NEXT: %shr = ashr i64 %a, %shr.mask
+  long c = a>>b;
+  long d = ((long)8)>>65;
+  //CHECK-NEXT: %add = add nsw i64 %shr, 4
+  long e = c + d;
+  //CHECK-NEXT: ret i64 %add
+  return e;
+}
diff --git a/test/Sema/shiftOpenCL.cl b/test/Sema/shiftOpenCL.cl
new file mode 100644
index 0000000..3bf9718
--- /dev/null
+++ b/test/Sema/shiftOpenCL.cl
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -x cl -O1 -emit-llvm  %s -o - -triple x86_64-linux-gnu | FileCheck %s
+// OpenCL essentially reduces all shift amounts to the last word-size bits before evaluating.
+// Test this both for variables and constants evaluated in the front-end.
+
+//CHECK: @array0 = common global [256 x i8]
+char array0[((int)1)<<40];
+//CHECK: @array1 = common global [256 x i8]
+char array1[((int)1)<<(-24)];
+
+//CHECK: @negativeShift32
+int negativeShift32(int a,int b) {
+  //CHECK: ret i32 65536
+  return ((int)1)<<(-16);
+}