r282453 - P0145R3 (C++17 evaluation order tweaks): consistently emit the LHS of array

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 26 16:49:47 PDT 2016


Author: rsmith
Date: Mon Sep 26 18:49:47 2016
New Revision: 282453

URL: http://llvm.org/viewvc/llvm-project?rev=282453&view=rev
Log:
P0145R3 (C++17 evaluation order tweaks): consistently emit the LHS of array
subscripting before the RHS, regardless of which is the base and which is the
index.

Added:
    cfe/trunk/test/CodeGenCXX/cxx1z-eval-order.cpp
Modified:
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/test/CodeGen/captured-statements-nested.c
    cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp
    cfe/trunk/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp
    cfe/trunk/test/CodeGenCXX/pragma-loop-safety.cpp
    cfe/trunk/test/CodeGenCXX/vla-lambda-capturing.cpp

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=282453&r1=282452&r2=282453&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Mon Sep 26 18:49:47 2016
@@ -2875,13 +2875,30 @@ static Address emitArraySubscriptGEP(Cod
 
 LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
                                                bool Accessed) {
-  // The index must always be an integer, which is not an aggregate.  Emit it.
-  llvm::Value *Idx = EmitScalarExpr(E->getIdx());
-  QualType IdxTy  = E->getIdx()->getType();
-  bool IdxSigned = IdxTy->isSignedIntegerOrEnumerationType();
+  // The index must always be an integer, which is not an aggregate.  Emit it
+  // in lexical order (this complexity is, sadly, required by C++17).
+  llvm::Value *IdxPre =
+      (E->getLHS() == E->getIdx()) ? EmitScalarExpr(E->getIdx()) : nullptr;
+  auto EmitIdxAfterBase = [&, IdxPre](bool Promote = true) -> llvm::Value * {
+    auto *Idx = IdxPre;
+    if (E->getLHS() != E->getIdx()) {
+      assert(E->getRHS() == E->getIdx() && "index was neither LHS nor RHS");
+      Idx = EmitScalarExpr(E->getIdx());
+    }
+
+    QualType IdxTy = E->getIdx()->getType();
+    bool IdxSigned = IdxTy->isSignedIntegerOrEnumerationType();
+
+    if (SanOpts.has(SanitizerKind::ArrayBounds))
+      EmitBoundsCheck(E, E->getBase(), Idx, IdxTy, Accessed);
 
-  if (SanOpts.has(SanitizerKind::ArrayBounds))
-    EmitBoundsCheck(E, E->getBase(), Idx, IdxTy, Accessed);
+    // Extend or truncate the index type to 32 or 64-bits.
+    if (Promote && Idx->getType() != IntPtrTy)
+      Idx = Builder.CreateIntCast(Idx, IntPtrTy, IdxSigned, "idxprom");
+
+    return Idx;
+  };
+  IdxPre = nullptr;
 
   // If the base is a vector type, then we are forming a vector element lvalue
   // with this subscript.
@@ -2889,6 +2906,7 @@ LValue CodeGenFunction::EmitArraySubscri
       !isa<ExtVectorElementExpr>(E->getBase())) {
     // Emit the vector as an lvalue to get its address.
     LValue LHS = EmitLValue(E->getBase());
+    auto *Idx = EmitIdxAfterBase(/*Promote*/false);
     assert(LHS.isSimple() && "Can only subscript lvalue vectors here!");
     return LValue::MakeVectorElt(LHS.getAddress(), Idx,
                                  E->getBase()->getType(),
@@ -2897,13 +2915,10 @@ LValue CodeGenFunction::EmitArraySubscri
 
   // All the other cases basically behave like simple offsetting.
 
-  // Extend or truncate the index type to 32 or 64-bits.
-  if (Idx->getType() != IntPtrTy)
-    Idx = Builder.CreateIntCast(Idx, IntPtrTy, IdxSigned, "idxprom");
-
   // Handle the extvector case we ignored above.
   if (isa<ExtVectorElementExpr>(E->getBase())) {
     LValue LV = EmitLValue(E->getBase());
+    auto *Idx = EmitIdxAfterBase(/*Promote*/true);
     Address Addr = EmitExtVectorElementLValue(LV);
 
     QualType EltType = LV.getType()->castAs<VectorType>()->getElementType();
@@ -2919,6 +2934,7 @@ LValue CodeGenFunction::EmitArraySubscri
     // it.  It needs to be emitted first in case it's what captures
     // the VLA bounds.
     Addr = EmitPointerWithAlignment(E->getBase(), &AlignSource);
+    auto *Idx = EmitIdxAfterBase(/*Promote*/true);
 
     // The element count here is the total number of non-VLA elements.
     llvm::Value *numElements = getVLASize(vla).first;
@@ -2938,14 +2954,16 @@ LValue CodeGenFunction::EmitArraySubscri
 
   } else if (const ObjCObjectType *OIT = E->getType()->getAs<ObjCObjectType>()){
     // Indexing over an interface, as in "NSString *P; P[4];"
-    CharUnits InterfaceSize = getContext().getTypeSizeInChars(OIT);
-    llvm::Value *InterfaceSizeVal = 
-      llvm::ConstantInt::get(Idx->getType(), InterfaceSize.getQuantity());;
-
-    llvm::Value *ScaledIdx = Builder.CreateMul(Idx, InterfaceSizeVal);
 
     // Emit the base pointer.
     Addr = EmitPointerWithAlignment(E->getBase(), &AlignSource);
+    auto *Idx = EmitIdxAfterBase(/*Promote*/true);
+
+    CharUnits InterfaceSize = getContext().getTypeSizeInChars(OIT);
+    llvm::Value *InterfaceSizeVal =
+        llvm::ConstantInt::get(Idx->getType(), InterfaceSize.getQuantity());
+
+    llvm::Value *ScaledIdx = Builder.CreateMul(Idx, InterfaceSizeVal);
 
     // We don't necessarily build correct LLVM struct types for ObjC
     // interfaces, so we can't rely on GEP to do this scaling
@@ -2977,6 +2995,7 @@ LValue CodeGenFunction::EmitArraySubscri
       ArrayLV = EmitArraySubscriptExpr(ASE, /*Accessed*/ true);
     else
       ArrayLV = EmitLValue(Array);
+    auto *Idx = EmitIdxAfterBase(/*Promote*/true);
 
     // Propagate the alignment from the array itself to the result.
     Addr = emitArraySubscriptGEP(*this, ArrayLV.getAddress(),
@@ -2987,6 +3006,7 @@ LValue CodeGenFunction::EmitArraySubscri
   } else {
     // The base must be a pointer; emit it with an estimate of its alignment.
     Addr = EmitPointerWithAlignment(E->getBase(), &AlignSource);
+    auto *Idx = EmitIdxAfterBase(/*Promote*/true);
     Addr = emitArraySubscriptGEP(*this, Addr, Idx, E->getType(),
                                  !getLangOpts().isSignedOverflowDefined());
   }

Modified: cfe/trunk/test/CodeGen/captured-statements-nested.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/captured-statements-nested.c?rev=282453&r1=282452&r2=282453&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/captured-statements-nested.c (original)
+++ cfe/trunk/test/CodeGen/captured-statements-nested.c Mon Sep 26 18:49:47 2016
@@ -69,7 +69,7 @@ void test_nest_captured_stmt(int param,
         // CHECK1-NEXT: getelementptr inbounds %struct.A, %struct.A*
         // CHECK1-NEXT: store i8 99
         //
-        // CHECK1: [[SIZE_ADDR_REF:%.*]] = getelementptr inbounds [[T]], [[T]]* {{.*}}, i{{.+}} 0, i{{.+}} 7
+        // CHECK1-DAG: [[SIZE_ADDR_REF:%.*]] = getelementptr inbounds [[T]], [[T]]* {{.*}}, i{{.+}} 0, i{{.+}} 7
         // CHECK1-DAG: [[SIZE_ADDR:%.*]] = load i{{.+}}*, i{{.+}}** [[SIZE_ADDR_REF]]
         // CHECK1-DAG: [[SIZE:%.*]] = load i{{.+}}, i{{.+}}* [[SIZE_ADDR]]
         // CHECK1-DAG: [[PARAM_ARR_IDX:%.*]] = sub nsw i{{.+}} [[SIZE]], 1
@@ -79,7 +79,7 @@ void test_nest_captured_stmt(int param,
         // CHECK1-DAG: [[PARAM_ARR_SIZE_MINUS_1_ADDR:%.*]] = getelementptr inbounds i{{.+}}, i{{.+}}* [[PARAM_ARR]], i{{.*}}
         // CHECK1: store i{{.+}} 2, i{{.+}}* [[PARAM_ARR_SIZE_MINUS_1_ADDR]]
         //
-        // CHECK1: [[Z_ADDR_REF:%.*]] = getelementptr inbounds [[T]], [[T]]* {{.*}}, i{{.+}} 0, i{{.+}} 2
+        // CHECK1-DAG: [[Z_ADDR_REF:%.*]] = getelementptr inbounds [[T]], [[T]]* {{.*}}, i{{.+}} 0, i{{.+}} 2
         // CHECK1-DAG: [[Z_ADDR:%.*]] = load %struct.A*, %struct.A** [[Z_ADDR_REF]]
         // CHECK1-DAG: [[Z_A_ADDR:%.*]] = getelementptr inbounds %struct.A, %struct.A* [[Z_ADDR]], i{{.+}} 0, i{{.+}} 0
         // CHECK1-DAG: [[ARR_IDX_2:%.*]] = load i{{.+}}, i{{.+}}* [[Z_A_ADDR]]

Modified: cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp?rev=282453&r1=282452&r2=282453&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp Mon Sep 26 18:49:47 2016
@@ -277,13 +277,13 @@ int array_index(const int (&a)[4], int n
 int multi_array_index(int n, int m) {
   int arr[4][6];
 
-  // CHECK: %[[IDX2_OK:.*]] = icmp ult i64 %{{.*}}, 6
-  // CHECK: br i1 %[[IDX2_OK]]
-  // CHECK: call void @__ubsan_handle_out_of_bounds(
-
   // CHECK: %[[IDX1_OK:.*]] = icmp ult i64 %{{.*}}, 4
   // CHECK: br i1 %[[IDX1_OK]]
   // CHECK: call void @__ubsan_handle_out_of_bounds(
+
+  // CHECK: %[[IDX2_OK:.*]] = icmp ult i64 %{{.*}}, 6
+  // CHECK: br i1 %[[IDX2_OK]]
+  // CHECK: call void @__ubsan_handle_out_of_bounds(
   return arr[n][m];
 }
 

Modified: cfe/trunk/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp?rev=282453&r1=282452&r2=282453&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp Mon Sep 26 18:49:47 2016
@@ -51,8 +51,8 @@ C n{};
 
 // CHECK: store i32 0, i32* getelementptr inbounds ({{.*}} @a, i32 0, i32 0)
 // CHECK: store i8* {{.*}} @[[STR_A]]{{.*}}, i8** getelementptr inbounds ({{.*}} @a, i32 0, i32 1)
-// CHECK: load i32, i32* getelementptr inbounds ({{.*}} @a, i32 0, i32 0)
 // CHECK: load i8*, i8** getelementptr inbounds ({{.*}} @a, i32 0, i32 1)
+// CHECK: load i32, i32* getelementptr inbounds ({{.*}} @a, i32 0, i32 0)
 // CHECK: getelementptr inbounds i8, i8* %{{.*}}, {{.*}} %{{.*}}
 // CHECK: store i8 %{{.*}}, i8* getelementptr inbounds ({{.*}} @a, i32 0, i32 2)
 // CHECK: call i32 @_ZN1A1fEv({{.*}} @a)

Added: cfe/trunk/test/CodeGenCXX/cxx1z-eval-order.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx1z-eval-order.cpp?rev=282453&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/cxx1z-eval-order.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/cxx1z-eval-order.cpp Mon Sep 26 18:49:47 2016
@@ -0,0 +1,214 @@
+// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple %itanium_abi_triple | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ITANIUM
+// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple %ms_abi_triple | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-WINDOWS
+
+struct B;
+struct A {
+  A();
+  A(const A&);
+
+  void operator[](B b);
+
+  int a_member_f(B);
+};
+struct B {
+  B();
+  ~B();
+};
+
+struct C {
+  operator int *();
+  A *operator->();
+  void operator->*(B);
+
+  friend void operator<<(C, B);
+  friend void operator>>(C, B);
+  void operator<<(A);
+  void operator>>(A);
+
+  void operator=(B);
+  void operator+=(B);
+};
+
+A make_a();
+A *make_a_ptr();
+int A::*make_mem_ptr_a();
+void (A::*make_mem_fn_ptr_a())();
+B make_b();
+C make_c();
+void side_effect();
+
+void callee(A);
+void (*get_f())(A);
+
+
+// CHECK-LABEL: define {{.*}}@{{.*}}postfix_before_args{{.*}}(
+void postfix_before_args() {
+  // CHECK: call {{.*}}@{{.*}}get_f{{.*}}(
+  // CHECK-ITANIUM: call {{.*}}@_ZN1AC1Ev(
+  // CHECK-WINDOWS: call {{.*}}@"\01??0A@@QEAA at XZ"(
+  // CHECK: call {{.*}}%{{.*}}(
+  get_f()(A{});
+
+  // CHECK: call {{.*}}@{{.*}}side_effect{{.*}}(
+  // CHECK-ITANIUM: call {{.*}}@_ZN1AC1Ev(
+  // CHECK-WINDOWS: call {{.*}}@"\01??0A@@QEAA at XZ"(
+  // CHECK: call {{.*}}@{{.*}}callee{{.*}}(
+  (side_effect(), callee)(A{});
+// CHECK: }
+}
+
+
+// CHECK-LABEL: define {{.*}}@{{.*}}dot_lhs_before_rhs{{.*}}(
+void dot_lhs_before_rhs() {
+  // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+  // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+  // CHECK: call {{.*}}@{{.*}}a_member_f{{.*}}(
+  make_a().a_member_f(make_b());
+
+  // CHECK: call {{.*}}@{{.*}}make_a_ptr{{.*}}(
+  // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+  // CHECK: call {{.*}}@{{.*}}a_member_f{{.*}}(
+  make_a_ptr()->a_member_f(make_b());
+
+  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+  // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+  // CHECK: call {{.*}}@{{.*}}a_member_f{{.*}}(
+  make_c()->a_member_f(make_b());
+// CHECK: }
+}
+
+
+// CHECK-LABEL: define {{.*}}@{{.*}}array_lhs_before_rhs{{.*}}(
+void array_lhs_before_rhs() {
+  int (&get_arr())[10];
+  extern int get_index();
+
+  // CHECK: call {{.*}}@{{.*}}get_arr{{.*}}(
+  // CHECK: call {{.*}}@{{.*}}get_index{{.*}}(
+  get_arr()[get_index()] = 0;
+
+  // CHECK: call {{.*}}@{{.*}}get_index{{.*}}(
+  // CHECK: call {{.*}}@{{.*}}get_arr{{.*}}(
+  get_index()[get_arr()] = 0;
+
+  // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+  // CHECK: call {{.*}}@{{.*}}make_b{{.*}}(
+  // CHECK: call
+  make_a()[make_b()];
+
+  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+  // CHECK: call {{.*}}@{{.*}}get_index{{.*}}(
+  // CHECK: call
+  make_c()[get_index()] = 0;
+
+  // CHECK: call {{.*}}@{{.*}}get_index{{.*}}(
+  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+  // CHECK: call
+  get_index()[make_c()] = 0;
+// CHECK: }
+}
+
+
+void *operator new(decltype(sizeof(0)), C);
+
+// CHECK-LABEL: define {{.*}}@{{.*}}alloc_before_init{{.*}}(
+void alloc_before_init() {
+  struct Q { Q(A) {} };
+  // CHECK-ITANIUM: call {{.*}}@_Znw{{.*}}(
+  // CHECK-WINDOWS: call {{.*}}@"\01??2 at YAPEAX_K@Z"(
+  // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+  delete new Q(make_a());
+
+  // CHECK: call {{.*}}@{{.*}}make_c{{.*}}(
+  // CHECK: call {{.*}}@{{.*}}make_a{{.*}}(
+  new (make_c()) Q(make_a());
+// CHECK: }
+}
+
+#if 0
+// CHECKDISABLED-LABEL: define {{.*}}@{{.*}}dotstar_lhs_before_rhs{{.*}}(
+int dotstar_lhs_before_rhs() {
+  // CHECKDISABLED: call {{.*}}@{{.*}}make_a{{.*}}(
+  // CHECKDISABLED: call {{.*}}@{{.*}}make_mem_ptr_a{{.*}}(
+  int a = make_a().*make_mem_ptr_a();
+
+  // CHECKDISABLED: call {{.*}}@{{.*}}make_a_ptr{{.*}}(
+  // CHECKDISABLED: call {{.*}}@{{.*}}make_mem_ptr_a{{.*}}(
+  int b = make_a_ptr()->*make_mem_ptr_a();
+
+  // CHECKDISABLED: call {{.*}}@{{.*}}make_c{{.*}}(
+  // CHECKDISABLED: call {{.*}}@{{.*}}make_b{{.*}}(
+  make_c()->*make_b();
+
+  // CHECKDISABLED: call {{.*}}@{{.*}}make_a{{.*}}(
+  // CHECKDISABLED: call {{.*}}@{{.*}}make_mem_fn_ptr_a{{.*}}(
+  // CHECKDISABLED: call
+  (make_a().*make_mem_fn_ptr_a())();
+
+  // CHECKDISABLED: call {{.*}}@{{.*}}make_a_ptr{{.*}}(
+  // CHECKDISABLED: call {{.*}}@{{.*}}make_mem_fn_ptr_a{{.*}}(
+  // CHECKDISABLED: call
+  (make_a_ptr()->*make_mem_fn_ptr_a())();
+
+  return a + b;
+// CHECKDISABLED: }
+}
+#endif
+#if 0
+// CHECKDISABLED-LABEL: define {{.*}}@{{.*}}assign_lhs_before_rhs{{.*}}(
+void assign_rhs_before_lhs() {
+  extern int &lhs_ref(), rhs();
+
+  // CHECKDISABLED: call {{.*}}@{{.*}}rhs{{.*}}(
+  // CHECKDISABLED: call {{.*}}@{{.*}}lhs_ref{{.*}}(
+  lhs_ref() = rhs();
+
+  // CHECKDISABLED: call {{.*}}@{{.*}}rhs{{.*}}(
+  // CHECKDISABLED: call {{.*}}@{{.*}}lhs_ref{{.*}}(
+  lhs_ref() += rhs();
+
+  // CHECKDISABLED: call {{.*}}@{{.*}}rhs{{.*}}(
+  // CHECKDISABLED: call {{.*}}@{{.*}}lhs_ref{{.*}}(
+  lhs_ref() %= rhs();
+
+  // CHECKDISABLED: call {{.*}}@{{.*}}make_b{{.*}}(
+  // CHECKDISABLED: call {{.*}}@{{.*}}make_c{{.*}}(
+  make_c() = make_b();
+
+  // CHECKDISABLED: call {{.*}}@{{.*}}make_b{{.*}}(
+  // CHECKDISABLED: call {{.*}}@{{.*}}make_c{{.*}}(
+  make_c() += make_b();
+// CHECKDISABLED: }
+}
+#endif
+#if 0
+// CHECKDISABLED-LABEL: define {{.*}}@{{.*}}shift_lhs_before_rhs{{.*}}(
+void shift_lhs_before_rhs() {
+  extern int lhs(), rhs();
+
+  // CHECKDISABLED: call {{.*}}@{{.*}}lhs{{.*}}(
+  // CHECKDISABLED: call {{.*}}@{{.*}}rhs{{.*}}(
+  (void)(lhs() << rhs());
+
+  // CHECKDISABLED: call {{.*}}@{{.*}}lhs{{.*}}(
+  // CHECKDISABLED: call {{.*}}@{{.*}}rhs{{.*}}(
+  (void)(lhs() >> rhs());
+
+  // CHECKDISABLED: call {{.*}}@{{.*}}make_c{{.*}}(
+  // CHECKDISABLED: call {{.*}}@{{.*}}make_a{{.*}}(
+  make_c() << make_a();
+
+  // CHECKDISABLED: call {{.*}}@{{.*}}make_c{{.*}}(
+  // CHECKDISABLED: call {{.*}}@{{.*}}make_a{{.*}}(
+  make_c() >> make_a();
+
+  // CHECKDISABLED: call {{.*}}@{{.*}}make_c{{.*}}(
+  // CHECKDISABLED: call {{.*}}@{{.*}}make_b{{.*}}(
+  make_c() << make_b();
+
+  // CHECKDISABLED: call {{.*}}@{{.*}}make_c{{.*}}(
+  // CHECKDISABLED: call {{.*}}@{{.*}}make_b{{.*}}(
+  make_c() >> make_b();
+// CHECKDISABLED: }
+}
+#endif

Modified: cfe/trunk/test/CodeGenCXX/pragma-loop-safety.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/pragma-loop-safety.cpp?rev=282453&r1=282452&r2=282453&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/pragma-loop-safety.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/pragma-loop-safety.cpp Mon Sep 26 18:49:47 2016
@@ -10,12 +10,12 @@ void vectorize_test(int *List, int Lengt
 #pragma clang loop vectorize(assume_safety) interleave(disable) unroll(disable)
   for (int i = 0; i < Length; i++) {
     // CHECK: [[RHIV1:.+]] = load i32, i32* [[IV1]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
-    // CHECK-NEXT: [[CALC1:.+]] = mul nsw i32[[RHIV1]], 2
-    // CHECK-NEXT: [[SIV1:.+]] = load i32, i32* [[IV1]]{{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
-    // CHECK-NEXT: [[INDEX1:.+]] = sext i32[[SIV1]] to i64
-    // CHECK-NEXT: [[ARRAY1:.+]] = load i32*, i32** [[LIST1:.*]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
-    // CHECK-NEXT: [[PTR1:.+]] = getelementptr inbounds i32, i32*[[ARRAY1]], i64[[INDEX1]]
-    // CHECK-NEXT: store i32[[CALC1]], i32*[[PTR1]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
+    // CHECK-DAG: [[CALC1:.+]] = mul nsw i32[[RHIV1]], 2
+    // CHECK-DAG: [[SIV1:.+]] = load i32, i32* [[IV1]]{{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
+    // CHECK-DAG: [[INDEX1:.+]] = sext i32[[SIV1]] to i64
+    // CHECK-DAG: [[ARRAY1:.+]] = load i32*, i32** [[LIST1:.*]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
+    // CHECK-DAG: [[PTR1:.+]] = getelementptr inbounds i32, i32*[[ARRAY1]], i64[[INDEX1]]
+    // CHECK: store i32[[CALC1]], i32*[[PTR1]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP1_ID]]
     // CHECK-NEXT: br label [[LOOP1_INC:[^,]+]]
     List[i] = i * 2;
 
@@ -33,12 +33,12 @@ void interleave_test(int *List, int Leng
 #pragma clang loop interleave(assume_safety) vectorize(disable) unroll(disable)
   for (int i = 0; i < Length; i++) {
     // CHECK: [[RHIV2:.+]] = load i32, i32* [[IV2]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
-    // CHECK-NEXT: [[CALC2:.+]] = mul nsw i32[[RHIV2]], 2
-    // CHECK-NEXT: [[SIV2:.+]] = load i32, i32* [[IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
-    // CHECK-NEXT: [[INDEX2:.+]] = sext i32[[SIV2]] to i64
-    // CHECK-NEXT: [[ARRAY2:.+]] = load i32*, i32** [[LIST2:.*]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
-    // CHECK-NEXT: [[PTR2:.+]] = getelementptr inbounds i32, i32*[[ARRAY2]], i64[[INDEX2]]
-    // CHECK-NEXT: store i32[[CALC2]], i32*[[PTR2]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
+    // CHECK-DAG: [[CALC2:.+]] = mul nsw i32[[RHIV2]], 2
+    // CHECK-DAG: [[SIV2:.+]] = load i32, i32* [[IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
+    // CHECK-DAG: [[INDEX2:.+]] = sext i32[[SIV2]] to i64
+    // CHECK-DAG: [[ARRAY2:.+]] = load i32*, i32** [[LIST2:.*]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
+    // CHECK-DAG: [[PTR2:.+]] = getelementptr inbounds i32, i32*[[ARRAY2]], i64[[INDEX2]]
+    // CHECK: store i32[[CALC2]], i32*[[PTR2]], {{.*}}!llvm.mem.parallel_loop_access ![[LOOP2_ID]]
     // CHECK-NEXT: br label [[LOOP2_INC:[^,]+]]
     List[i] = i * 2;
 

Modified: cfe/trunk/test/CodeGenCXX/vla-lambda-capturing.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/vla-lambda-capturing.cpp?rev=282453&r1=282452&r2=282453&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/vla-lambda-capturing.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/vla-lambda-capturing.cpp Mon Sep 26 18:49:47 2016
@@ -125,11 +125,11 @@ int main() {
 // CHECK: [[SIZE2:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIZE2_REF]]
 // CHECK: [[SIZE1_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
 // CHECK: [[SIZE1:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIZE1_REF]]
+// CHECK: [[BUFFER1_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+// CHECK: [[BUFFER1_ADDR:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[BUFFER1_ADDR_REF]]
 // CHECK: [[N_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
 // CHECK: [[N_ADDR:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[N_ADDR_REF]]
 // CHECK: [[N:%.+]] = load [[INTPTR_T]], [[INTPTR_T]]* [[N_ADDR]]
-// CHECK: [[BUFFER1_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
-// CHECK: [[BUFFER1_ADDR:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[BUFFER1_ADDR_REF]]
 // CHECK: [[ELEM_OFFSET:%.+]] = mul {{.*}} i{{[0-9]+}} [[N]], [[SIZE1]]
 // CHECK: [[ELEM_ADDR:%.+]] = getelementptr inbounds [[INTPTR_T]], [[INTPTR_T]]* [[BUFFER1_ADDR]], i{{[0-9]+}} [[ELEM_OFFSET]]
 // CHECK: [[SIZEOF:%.+]] = mul {{.*}} i{{[0-9]+}} {{[0-9]+}}, [[SIZE1]]




More information about the cfe-commits mailing list