Author: abataev Date: Tue May 10 04:57:36 2016 New Revision: 269035 URL: http://llvm.org/viewvc/llvm-project?rev=269035&view=rev Log: [OPENMP 4.5] Add codegen support in runtime for '[non]monotonic' schedule modifiers.
Runtime library expects some additional data in schedule argument for loop-based directives, that have additional schedule modifiers 'monotonic|nonmonotonic'. Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.h cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.h cfe/trunk/test/OpenMP/for_codegen.cpp cfe/trunk/test/OpenMP/for_simd_codegen.cpp Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.h?rev=269035&r1=269034&r2=269035&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/OpenMPKinds.h (original) +++ cfe/trunk/include/clang/Basic/OpenMPKinds.h Tue May 10 04:57:36 2016 @@ -120,6 +120,13 @@ enum OpenMPDefaultmapClauseModifier { OMPC_DEFAULTMAP_MODIFIER_last }; +/// Scheduling data for loop-based OpenMP directives. +struct OpenMPScheduleTy final { + OpenMPScheduleClauseKind Schedule = OMPC_SCHEDULE_unknown; + OpenMPScheduleClauseModifier M1 = OMPC_SCHEDULE_MODIFIER_unknown; + OpenMPScheduleClauseModifier M2 = OMPC_SCHEDULE_MODIFIER_unknown; +}; + OpenMPDirectiveKind getOpenMPDirectiveKind(llvm::StringRef Str); const char *getOpenMPDirectiveName(OpenMPDirectiveKind Kind); Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp?rev=269035&r1=269034&r2=269035&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp (original) +++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp Tue May 10 04:57:36 2016 @@ -500,6 +500,11 @@ enum OpenMPSchedType { /// \brief dist_schedule types OMP_dist_sch_static_chunked = 91, OMP_dist_sch_static = 92, + /// Support for OpenMP 4.5 monotonic and nonmonotonic schedule modifiers. + /// Set if the monotonic schedule modifier was present. + OMP_sch_modifier_monotonic = (1 << 29), + /// Set if the nonmonotonic schedule modifier was present. + OMP_sch_modifier_nonmonotonic = (1 << 30), }; enum OpenMPRTLFunction { @@ -2333,16 +2338,42 @@ bool CGOpenMPRuntime::isDynamic(OpenMPSc return Schedule != OMP_sch_static; } +static int addMonoNonMonoModifier(OpenMPSchedType Schedule, + OpenMPScheduleClauseModifier M1, + OpenMPScheduleClauseModifier M2) { + switch (M1) { + case OMPC_SCHEDULE_MODIFIER_monotonic: + return Schedule | OMP_sch_modifier_monotonic; + case OMPC_SCHEDULE_MODIFIER_nonmonotonic: + return Schedule | OMP_sch_modifier_nonmonotonic; + case OMPC_SCHEDULE_MODIFIER_simd: + case OMPC_SCHEDULE_MODIFIER_last: + case OMPC_SCHEDULE_MODIFIER_unknown: + break; + } + switch (M2) { + case OMPC_SCHEDULE_MODIFIER_monotonic: + return Schedule | OMP_sch_modifier_monotonic; + case OMPC_SCHEDULE_MODIFIER_nonmonotonic: + return Schedule | OMP_sch_modifier_nonmonotonic; + case OMPC_SCHEDULE_MODIFIER_simd: + case OMPC_SCHEDULE_MODIFIER_last: + case OMPC_SCHEDULE_MODIFIER_unknown: + break; + } + return Schedule; +} + void CGOpenMPRuntime::emitForDispatchInit(CodeGenFunction &CGF, SourceLocation Loc, - OpenMPScheduleClauseKind ScheduleKind, + const OpenMPScheduleTy &ScheduleKind, unsigned IVSize, bool IVSigned, bool Ordered, llvm::Value *UB, llvm::Value *Chunk) { if (!CGF.HaveInsertPoint()) return; OpenMPSchedType Schedule = - getRuntimeSchedule(ScheduleKind, Chunk != nullptr, Ordered); + getRuntimeSchedule(ScheduleKind.Schedule, Chunk != nullptr, Ordered); assert(Ordered || (Schedule != OMP_sch_static && Schedule != OMP_sch_static_chunked && Schedule != OMP_ord_static && Schedule != OMP_ord_static_chunked)); @@ -2355,26 +2386,23 @@ void CGOpenMPRuntime::emitForDispatchIni if (Chunk == nullptr) Chunk = CGF.Builder.getIntN(IVSize, 1); llvm::Value *Args[] = { - emitUpdateLocation(CGF, Loc), - getThreadID(CGF, Loc), - CGF.Builder.getInt32(Schedule), // Schedule type - CGF.Builder.getIntN(IVSize, 0), // Lower - UB, // Upper - CGF.Builder.getIntN(IVSize, 1), // Stride - Chunk // Chunk + emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc), + CGF.Builder.getInt32(addMonoNonMonoModifier( + Schedule, ScheduleKind.M1, ScheduleKind.M2)), // Schedule type + CGF.Builder.getIntN(IVSize, 0), // Lower + UB, // Upper + CGF.Builder.getIntN(IVSize, 1), // Stride + Chunk // Chunk }; CGF.EmitRuntimeCall(createDispatchInitFunction(IVSize, IVSigned), Args); } -static void emitForStaticInitCall(CodeGenFunction &CGF, - SourceLocation Loc, - llvm::Value * UpdateLocation, - llvm::Value * ThreadId, - llvm::Constant * ForStaticInitFunction, - OpenMPSchedType Schedule, - unsigned IVSize, bool IVSigned, bool Ordered, - Address IL, Address LB, Address UB, - Address ST, llvm::Value *Chunk) { +static void emitForStaticInitCall( + CodeGenFunction &CGF, llvm::Value *UpdateLocation, llvm::Value *ThreadId, + llvm::Constant *ForStaticInitFunction, OpenMPSchedType Schedule, + OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, + unsigned IVSize, bool Ordered, Address IL, Address LB, Address UB, + Address ST, llvm::Value *Chunk) { if (!CGF.HaveInsertPoint()) return; @@ -2402,47 +2430,48 @@ static void emitForStaticInitCall(CodeGe "expected static chunked schedule"); } llvm::Value *Args[] = { - UpdateLocation, - ThreadId, - CGF.Builder.getInt32(Schedule), // Schedule type - IL.getPointer(), // &isLastIter - LB.getPointer(), // &LB - UB.getPointer(), // &UB - ST.getPointer(), // &Stride - CGF.Builder.getIntN(IVSize, 1), // Incr - Chunk // Chunk + UpdateLocation, ThreadId, CGF.Builder.getInt32(addMonoNonMonoModifier( + Schedule, M1, M2)), // Schedule type + IL.getPointer(), // &isLastIter + LB.getPointer(), // &LB + UB.getPointer(), // &UB + ST.getPointer(), // &Stride + CGF.Builder.getIntN(IVSize, 1), // Incr + Chunk // Chunk }; CGF.EmitRuntimeCall(ForStaticInitFunction, Args); } void CGOpenMPRuntime::emitForStaticInit(CodeGenFunction &CGF, SourceLocation Loc, - OpenMPScheduleClauseKind ScheduleKind, + const OpenMPScheduleTy &ScheduleKind, unsigned IVSize, bool IVSigned, bool Ordered, Address IL, Address LB, Address UB, Address ST, llvm::Value *Chunk) { - OpenMPSchedType ScheduleNum = getRuntimeSchedule(ScheduleKind, Chunk != nullptr, - Ordered); + OpenMPSchedType ScheduleNum = + getRuntimeSchedule(ScheduleKind.Schedule, Chunk != nullptr, Ordered); auto *UpdatedLocation = emitUpdateLocation(CGF, Loc); auto *ThreadId = getThreadID(CGF, Loc); auto *StaticInitFunction = createForStaticInitFunction(IVSize, IVSigned); - emitForStaticInitCall(CGF, Loc, UpdatedLocation, ThreadId, StaticInitFunction, - ScheduleNum, IVSize, IVSigned, Ordered, IL, LB, UB, ST, Chunk); + emitForStaticInitCall(CGF, UpdatedLocation, ThreadId, StaticInitFunction, + ScheduleNum, ScheduleKind.M1, ScheduleKind.M2, IVSize, + Ordered, IL, LB, UB, ST, Chunk); } -void CGOpenMPRuntime::emitDistributeStaticInit(CodeGenFunction &CGF, - SourceLocation Loc, OpenMPDistScheduleClauseKind SchedKind, - unsigned IVSize, bool IVSigned, - bool Ordered, Address IL, Address LB, - Address UB, Address ST, +void CGOpenMPRuntime::emitDistributeStaticInit( + CodeGenFunction &CGF, SourceLocation Loc, + OpenMPDistScheduleClauseKind SchedKind, unsigned IVSize, bool IVSigned, + bool Ordered, Address IL, Address LB, Address UB, Address ST, llvm::Value *Chunk) { OpenMPSchedType ScheduleNum = getRuntimeSchedule(SchedKind, Chunk != nullptr); auto *UpdatedLocation = emitUpdateLocation(CGF, Loc); auto *ThreadId = getThreadID(CGF, Loc); auto *StaticInitFunction = createForStaticInitFunction(IVSize, IVSigned); - emitForStaticInitCall(CGF, Loc, UpdatedLocation, ThreadId, StaticInitFunction, - ScheduleNum, IVSize, IVSigned, Ordered, IL, LB, UB, ST, Chunk); + emitForStaticInitCall(CGF, UpdatedLocation, ThreadId, StaticInitFunction, + ScheduleNum, OMPC_SCHEDULE_MODIFIER_unknown, + OMPC_SCHEDULE_MODIFIER_unknown, IVSize, Ordered, IL, LB, + UB, ST, Chunk); } void CGOpenMPRuntime::emitForStaticFinish(CodeGenFunction &CGF, Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h?rev=269035&r1=269034&r2=269035&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h (original) +++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h Tue May 10 04:57:36 2016 @@ -628,9 +628,9 @@ public: virtual bool isDynamic(OpenMPScheduleClauseKind ScheduleKind) const; virtual void emitForDispatchInit(CodeGenFunction &CGF, SourceLocation Loc, - OpenMPScheduleClauseKind SchedKind, - unsigned IVSize, bool IVSigned, - bool Ordered, llvm::Value *UB, + const OpenMPScheduleTy &ScheduleKind, + unsigned IVSize, bool IVSigned, bool Ordered, + llvm::Value *UB, llvm::Value *Chunk = nullptr); /// \brief Call the appropriate runtime routine to initialize it before start @@ -642,7 +642,7 @@ public: /// /// \param CGF Reference to current CodeGenFunction. /// \param Loc Clang source location. - /// \param SchedKind Schedule kind, specified by the 'schedule' clause. + /// \param ScheduleKind Schedule kind, specified by the 'schedule' clause. /// \param IVSize Size of the iteration variable in bits. /// \param IVSigned Sign of the interation variable. /// \param Ordered true if loop is ordered, false otherwise. @@ -658,10 +658,9 @@ public: /// For the default (nullptr) value, the chunk 1 will be used. /// virtual void emitForStaticInit(CodeGenFunction &CGF, SourceLocation Loc, - OpenMPScheduleClauseKind SchedKind, + const OpenMPScheduleTy &ScheduleKind, unsigned IVSize, bool IVSigned, bool Ordered, - Address IL, Address LB, - Address UB, Address ST, + Address IL, Address LB, Address UB, Address ST, llvm::Value *Chunk = nullptr); /// Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=269035&r1=269034&r2=269035&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original) +++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Tue May 10 04:57:36 2016 @@ -1729,16 +1729,18 @@ void CodeGenFunction::EmitOMPOuterLoop(b } void CodeGenFunction::EmitOMPForOuterLoop( - OpenMPScheduleClauseKind ScheduleKind, bool IsMonotonic, + const OpenMPScheduleTy &ScheduleKind, bool IsMonotonic, const OMPLoopDirective &S, OMPPrivateScope &LoopScope, bool Ordered, Address LB, Address UB, Address ST, Address IL, llvm::Value *Chunk) { auto &RT = CGM.getOpenMPRuntime(); // Dynamic scheduling of the outer loop (dynamic, guided, auto, runtime). - const bool DynamicOrOrdered = Ordered || RT.isDynamic(ScheduleKind); + const bool DynamicOrOrdered = + Ordered || RT.isDynamic(ScheduleKind.Schedule); assert((Ordered || - !RT.isStaticNonchunked(ScheduleKind, /*Chunked=*/Chunk != nullptr)) && + !RT.isStaticNonchunked(ScheduleKind.Schedule, + /*Chunked=*/Chunk != nullptr)) && "static non-chunked schedule does not need outer loop"); // Emit outer loop. @@ -1797,8 +1799,8 @@ void CodeGenFunction::EmitOMPForOuterLoo if (DynamicOrOrdered) { llvm::Value *UBVal = EmitScalarExpr(S.getLastIteration()); - RT.emitForDispatchInit(*this, S.getLocStart(), ScheduleKind, - IVSize, IVSigned, Ordered, UBVal, Chunk); + RT.emitForDispatchInit(*this, S.getLocStart(), ScheduleKind, IVSize, + IVSigned, Ordered, UBVal, Chunk); } else { RT.emitForStaticInit(*this, S.getLocStart(), ScheduleKind, IVSize, IVSigned, Ordered, IL, LB, UB, ST, Chunk); @@ -1923,13 +1925,11 @@ bool CodeGenFunction::EmitOMPWorksharing // Detect the loop schedule kind and chunk. llvm::Value *Chunk = nullptr; - OpenMPScheduleClauseKind ScheduleKind = OMPC_SCHEDULE_unknown; - OpenMPScheduleClauseModifier M1 = OMPC_SCHEDULE_MODIFIER_unknown; - OpenMPScheduleClauseModifier M2 = OMPC_SCHEDULE_MODIFIER_unknown; + OpenMPScheduleTy ScheduleKind; if (auto *C = S.getSingleClause<OMPScheduleClause>()) { - ScheduleKind = C->getScheduleKind(); - M1 = C->getFirstScheduleModifier(); - M2 = C->getSecondScheduleModifier(); + ScheduleKind.Schedule = C->getScheduleKind(); + ScheduleKind.M1 = C->getFirstScheduleModifier(); + ScheduleKind.M2 = C->getSecondScheduleModifier(); if (const auto *Ch = C->getChunkSize()) { Chunk = EmitScalarExpr(Ch); Chunk = EmitScalarConversion(Chunk, Ch->getType(), @@ -1944,7 +1944,7 @@ bool CodeGenFunction::EmitOMPWorksharing // If the static schedule kind is specified or if the ordered clause is // specified, and if no monotonic modifier is specified, the effect will // be as if the monotonic modifier was specified. - if (RT.isStaticNonchunked(ScheduleKind, + if (RT.isStaticNonchunked(ScheduleKind.Schedule, /* Chunked */ Chunk != nullptr) && !Ordered) { if (isOpenMPSimdDirective(S.getDirectiveKind())) @@ -1976,11 +1976,11 @@ bool CodeGenFunction::EmitOMPWorksharing // Tell the runtime we are done. RT.emitForStaticFinish(*this, S.getLocStart()); } else { - const bool IsMonotonic = Ordered || - ScheduleKind == OMPC_SCHEDULE_static || - ScheduleKind == OMPC_SCHEDULE_unknown || - M1 == OMPC_SCHEDULE_MODIFIER_monotonic || - M2 == OMPC_SCHEDULE_MODIFIER_monotonic; + const bool IsMonotonic = + Ordered || ScheduleKind.Schedule == OMPC_SCHEDULE_static || + ScheduleKind.Schedule == OMPC_SCHEDULE_unknown || + ScheduleKind.M1 == OMPC_SCHEDULE_MODIFIER_monotonic || + ScheduleKind.M2 == OMPC_SCHEDULE_MODIFIER_monotonic; // Emit the outer loop, which requests its work chunk [LB..UB] from // runtime and runs the inner loop to process it. EmitOMPForOuterLoop(ScheduleKind, IsMonotonic, S, LoopScope, Ordered, @@ -2147,8 +2147,10 @@ void CodeGenFunction::EmitSections(const (void)LoopScope.Privatize(); // Emit static non-chunked loop. + OpenMPScheduleTy ScheduleKind; + ScheduleKind.Schedule = OMPC_SCHEDULE_static; CGF.CGM.getOpenMPRuntime().emitForStaticInit( - CGF, S.getLocStart(), OMPC_SCHEDULE_static, /*IVSize=*/32, + CGF, S.getLocStart(), ScheduleKind, /*IVSize=*/32, /*IVSigned=*/true, /*Ordered=*/false, IL.getAddress(), LB.getAddress(), UB.getAddress(), ST.getAddress()); // UB = min(UB, GlobalUB); Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=269035&r1=269034&r2=269035&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original) +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue May 10 04:57:36 2016 @@ -2434,7 +2434,7 @@ private: void EmitOMPOuterLoop(bool IsMonotonic, bool DynamicOrOrdered, const OMPLoopDirective &S, OMPPrivateScope &LoopScope, bool Ordered, Address LB, Address UB, Address ST, Address IL, llvm::Value *Chunk); - void EmitOMPForOuterLoop(OpenMPScheduleClauseKind ScheduleKind, + void EmitOMPForOuterLoop(const OpenMPScheduleTy &ScheduleKind, bool IsMonotonic, const OMPLoopDirective &S, OMPPrivateScope &LoopScope, bool Ordered, Address LB, Address UB, Address ST, Address IL, Modified: cfe/trunk/test/OpenMP/for_codegen.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_codegen.cpp?rev=269035&r1=269034&r2=269035&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/for_codegen.cpp (original) +++ cfe/trunk/test/OpenMP/for_codegen.cpp Tue May 10 04:57:36 2016 @@ -98,8 +98,8 @@ void static_not_chunked(float *a, float // CHECK-LABEL: define {{.*void}} @{{.*}}static_chunked{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}}) void static_chunked(float *a, float *b, float *c, float *d) { // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]]) - #pragma omp for schedule(static, 5) -// CHECK: call void @__kmpc_for_static_init_4u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 33, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 5) + #pragma omp for schedule(monotonic: static, 5) +// CHECK: call void @__kmpc_for_static_init_4u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 536870945, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 5) // UB = min(UB, GlobalUB) // CHECK: [[UB:%.+]] = load i32, i32* [[OMP_UB]] // CHECK-NEXT: [[UBCMP:%.+]] = icmp ugt i32 [[UB]], 16908288 @@ -158,8 +158,8 @@ void static_chunked(float *a, float *b, // CHECK-LABEL: define {{.*void}} @{{.*}}dynamic1{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}}) void dynamic1(float *a, float *b, float *c, float *d) { // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]]) - #pragma omp for schedule(dynamic) -// CHECK: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 35, i64 0, i64 16908287, i64 1, i64 1) + #pragma omp for schedule(nonmonotonic: dynamic) +// CHECK: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 1073741859, i64 0, i64 16908287, i64 1, i64 1) // // CHECK: [[HASWORK:%.+]] = call i32 @__kmpc_dispatch_next_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32* [[OMP_ISLAST:%[^,]+]], i64* [[OMP_LB:%[^,]+]], i64* [[OMP_UB:%[^,]+]], i64* [[OMP_ST:%[^,]+]]) // CHECK-NEXT: [[O_CMP:%.+]] = icmp ne i32 [[HASWORK]], 0 Modified: cfe/trunk/test/OpenMP/for_simd_codegen.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_simd_codegen.cpp?rev=269035&r1=269034&r2=269035&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/for_simd_codegen.cpp (original) +++ cfe/trunk/test/OpenMP/for_simd_codegen.cpp Tue May 10 04:57:36 2016 @@ -54,13 +54,13 @@ void simple(float *a, float *b, float *c long long k = get_val(); - #pragma omp for simd linear(k : 3) schedule(dynamic) + #pragma omp for simd linear(k : 3) schedule(simd, nonmonotonic: dynamic) // CHECK: [[K0:%.+]] = call {{.*}}i64 @{{.*}}get_val // CHECK-NEXT: store i64 [[K0]], i64* [[K_VAR:%[^,]+]] // CHECK: [[K0LOAD:%.+]] = load i64, i64* [[K_VAR]] // CHECK-NEXT: store i64 [[K0LOAD]], i64* [[LIN0:%[^,]+]] -// CHECK: call void @__kmpc_dispatch_init_4(%ident_t* {{.+}}, i32 %{{.+}}, i32 35, i32 0, i32 8, i32 1, i32 1) +// CHECK: call void @__kmpc_dispatch_init_4(%ident_t* {{.+}}, i32 %{{.+}}, i32 1073741859, i32 0, i32 8, i32 1, i32 1) // CHECK: [[NEXT:%.+]] = call i32 @__kmpc_dispatch_next_4(%ident_t* {{.+}}, i32 %{{.+}}, i32* %{{.+}}, i32* [[LB:%.+]], i32* [[UB:%.+]], i32* %{{.+}}) // CHECK: [[COND:%.+]] = icmp ne i32 [[NEXT]], 0 // CHECK: br i1 [[COND]], label %[[CONT:.+]], label %[[END:.+]] _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits