; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature ; RUN: opt -S -openmpopt < %s | FileCheck %s ; RUN: opt -S -passes=openmpopt < %s | FileCheck %s %struct.ident_t = type { i32, i32, i32, i32, i8* } @.str = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1 @0 = private unnamed_addr global %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i32 0, i32 0) }, align 8 ; doesn't modify any ICVs. define i32 @icv_free_use(i32 %0) { ; CHECK-LABEL: define {{[^@]+}}@icv_free_use ; CHECK-SAME: (i32 [[TMP0:%.*]]) ; CHECK-NEXT: [[TMP2:%.*]] = add nsw i32 [[TMP0]], 1 ; CHECK-NEXT: ret i32 [[TMP2]] ; %2 = add nsw i32 %0, 1 ret i32 %2 } define i32 @bad_use(i32 %0) { ; CHECK-LABEL: define {{[^@]+}}@bad_use ; CHECK-SAME: (i32 [[TMP0:%.*]]) ; CHECK-NEXT: tail call void @use(i32 [[TMP0]]) ; CHECK-NEXT: [[TMP2:%.*]] = add nsw i32 [[TMP0]], 1 ; CHECK-NEXT: ret i32 [[TMP2]] ; tail call void @use(i32 %0) %2 = add nsw i32 %0, 1 ret i32 %2 } define void @indirect_call(void ()* %0) { ; CHECK-LABEL: define {{[^@]+}}@indirect_call ; CHECK-SAME: (void ()* [[TMP0:%.*]]) ; CHECK-NEXT: call void @omp_set_num_threads(i32 4) ; CHECK-NEXT: tail call void [[TMP0]]() ; CHECK-NEXT: [[TMP2:%.*]] = tail call i32 @omp_get_max_threads() ; CHECK-NEXT: tail call void @use(i32 [[TMP2]]) ; CHECK-NEXT: ret void call void @omp_set_num_threads(i32 4) tail call void %0() %2 = tail call i32 @omp_get_max_threads() tail call void @use(i32 %2) ret void } define dso_local i32 @foo(i32 %0, i32 %1) { ; CHECK-LABEL: define {{[^@]+}}@foo ; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) ; CHECK-NEXT: tail call void @omp_set_num_threads(i32 [[TMP0]]) ; CHECK-NEXT: tail call void @omp_set_num_threads(i32 [[TMP1]]) ; CHECK-NEXT: tail call void @use(i32 [[TMP1]]) ; CHECK-NEXT: tail call void @use(i32 [[TMP1]]) ; CHECK-NEXT: tail call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*)) ; CHECK-NEXT: [[TMP3:%.*]] = tail call i32 @omp_get_max_threads() ; CHECK-NEXT: tail call void @use(i32 [[TMP3]]) ; CHECK-NEXT: ret i32 0 ; tail call void @omp_set_num_threads(i32 %0) %3 = tail call i32 @omp_get_max_threads() ; FIXME: this value should be tracked and the rest of the getters deduplicated and replaced with it. tail call void @omp_set_num_threads(i32 %1) %4 = tail call i32 @omp_get_max_threads() %5 = tail call i32 @omp_get_max_threads() %6 = tail call i32 @omp_get_max_threads() tail call void @use(i32 %4) tail call void @use(i32 %5) tail call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*)) %7 = tail call i32 @omp_get_max_threads() tail call void @use(i32 %7) ret i32 0 } declare dso_local void @omp_set_num_threads(i32) declare dso_local i32 @omp_get_max_threads() declare dso_local void @use(i32) define internal void @.omp_outlined.(i32* %0, i32* %1) { ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined. ; CHECK-SAME: (i32* [[TMP0:%.*]], i32* [[TMP1:%.*]]) ; CHECK-NEXT: [[TMP3:%.*]] = tail call i32 @omp_get_max_threads() ; CHECK-NEXT: [[TMP4:%.*]] = tail call i32 @omp_get_max_threads() ; CHECK-NEXT: tail call void @use(i32 [[TMP4]]) ; CHECK-NEXT: tail call void @omp_set_num_threads(i32 10) ; CHECK-NEXT: tail call void @use(i32 10) ; CHECK-NEXT: ret void ; ; FIXME: this value should be tracked and the rest of the getters deduplicated and replaced with it. %3 = tail call i32 @omp_get_max_threads() %4 = tail call i32 @omp_get_max_threads() tail call void @use(i32 %4) tail call void @omp_set_num_threads(i32 10) %5 = tail call i32 @omp_get_max_threads() tail call void @use(i32 %5) ret void } declare !callback !0 void @__kmpc_fork_call(%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) define dso_local i32 @bar(i32 %0, i32 %1) { ; CHECK-LABEL: define {{[^@]+}}@bar ; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) ; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], [[TMP1]] ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i32 [[TMP0]], i32 [[TMP1]] ; CHECK-NEXT: tail call void @omp_set_num_threads(i32 [[TMP4]]) ; CHECK-NEXT: tail call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*)) ; CHECK-NEXT: [[TMP5:%.*]] = tail call i32 @omp_get_max_threads() ; CHECK-NEXT: tail call void @use(i32 [[TMP5]]) ; CHECK-NEXT: ret i32 0 ; %3 = icmp sgt i32 %0, %1 %4 = select i1 %3, i32 %0, i32 %1 ; FIXME: getters can be replaced with %4 tail call void @omp_set_num_threads(i32 %4) %5 = tail call i32 @omp_get_max_threads() tail call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*)) %6 = tail call i32 @omp_get_max_threads() tail call void @use(i32 %6) ret i32 0 } define internal void @.omp_outlined..1(i32* %0, i32* %1) { ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..1 ; CHECK-SAME: (i32* [[TMP0:%.*]], i32* [[TMP1:%.*]]) ; CHECK-NEXT: [[TMP3:%.*]] = tail call i32 @omp_get_max_threads() ; CHECK-NEXT: tail call void @use(i32 [[TMP3]]) ; CHECK-NEXT: tail call void @omp_set_num_threads(i32 10) ; CHECK-NEXT: tail call void @use(i32 10) ; CHECK-NEXT: [[TMP4:%.*]] = tail call i32 @omp_get_max_threads() ; CHECK-NEXT: tail call void @use(i32 [[TMP4]]) ; CHECK-NEXT: ret void ; %3 = tail call i32 @omp_get_max_threads() tail call void @use(i32 %3) tail call void @omp_set_num_threads(i32 10) %4 = tail call i32 @omp_get_max_threads() tail call void @use(i32 %4) %5 = tail call i32 @omp_get_max_threads() tail call void @use(i32 %5) ret void } define dso_local i32 @bar1(i32 %0, i32 %1) { ; CHECK-LABEL: define {{[^@]+}}@bar1 ; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) ; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], [[TMP1]] ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i32 [[TMP0]], i32 [[TMP1]] ; CHECK-NEXT: tail call void @omp_set_num_threads(i32 [[TMP4]]) ; CHECK-NEXT: tail call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..2 to void (i32*, i32*, ...)*)) ; CHECK-NEXT: [[TMP5:%.*]] = tail call i32 @omp_get_max_threads() ; CHECK-NEXT: tail call void @use(i32 [[TMP5]]) ; CHECK-NEXT: ret i32 0 ; %3 = icmp sgt i32 %0, %1 %4 = select i1 %3, i32 %0, i32 %1 tail call void @omp_set_num_threads(i32 %4) %5 = tail call i32 @omp_get_max_threads() tail call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..2 to void (i32*, i32*, ...)*)) %6 = tail call i32 @omp_get_max_threads() tail call void @use(i32 %6) ret i32 0 } define internal void @.omp_outlined..2(i32* %0, i32* %1) { ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..2 ; CHECK-SAME: (i32* [[TMP0:%.*]], i32* [[TMP1:%.*]]) ; CHECK-NEXT: [[TMP3:%.*]] = tail call i32 @omp_get_max_threads() ; CHECK-NEXT: [[TMP4:%.*]] = tail call i32 @icv_free_use(i32 [[TMP3]]) ; CHECK-NEXT: tail call void @omp_set_num_threads(i32 10) ; CHECK-NEXT: [[TMP5:%.*]] = tail call i32 @icv_free_use(i32 10) ; CHECK-NEXT: [[TMP6:%.*]] = tail call i32 @icv_free_use(i32 10) ; CHECK-NEXT: ret void ; %3 = tail call i32 @omp_get_max_threads() %4 = tail call i32 @icv_free_use(i32 %3) tail call void @omp_set_num_threads(i32 10) %5 = tail call i32 @omp_get_max_threads() %6 = tail call i32 @icv_free_use(i32 %5) %7 = tail call i32 @omp_get_max_threads() %8 = tail call i32 @icv_free_use(i32 %7) ret void } define void @test(i1 %0) { ; CHECK-LABEL: define {{[^@]+}}@test ; CHECK-SAME: (i1 [[TMP0:%.*]]) ; CHECK-NEXT: call void @omp_set_num_threads(i32 2) ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i1 [[TMP0]], false ; CHECK-NEXT: br i1 [[TMP2]], label [[TMP4:%.*]], label [[TMP3:%.*]] ; CHECK: 3: ; CHECK-NEXT: call void @use(i32 10) ; CHECK-NEXT: br label [[TMP4]] ; CHECK: 4: ; CHECK-NEXT: [[TMP5:%.*]] = call i32 @omp_get_max_threads() ; CHECK-NEXT: call void @use(i32 [[TMP5]]) ; CHECK-NEXT: ret void ; call void @omp_set_num_threads(i32 2) %2 = icmp eq i1 %0, 0 br i1 %2, label %4, label %3 3: ; preds = %1 call void @use(i32 10) br label %4 4: ; preds = %3, %1 %5 = call i32 @omp_get_max_threads() call void @use(i32 %5) ret void } define void @test1(i1 %0) { ; CHECK-LABEL: define {{[^@]+}}@test1 ; CHECK-SAME: (i1 [[TMP0:%.*]]) ; CHECK-NEXT: call void @omp_set_num_threads(i32 2) ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i1 [[TMP0]], false ; CHECK-NEXT: br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]] ; CHECK: 3: ; CHECK-NEXT: [[TMP4:%.*]] = call i32 @icv_free_use(i32 10) ; CHECK-NEXT: br label [[TMP5]] ; CHECK: 5: ; CHECK-NEXT: call void @use(i32 2) ; CHECK-NEXT: ret void ; call void @omp_set_num_threads(i32 2) %2 = icmp eq i1 %0, 0 br i1 %2, label %5, label %3 3: ; preds = %1 %4 = call i32 @icv_free_use(i32 10) br label %5 5: ; preds = %3, %1 %6 = call i32 @omp_get_max_threads() call void @use(i32 %6) ret void } define void @bad_use_test(i1 %0) { ; CHECK-LABEL: define {{[^@]+}}@bad_use_test ; CHECK-SAME: (i1 [[TMP0:%.*]]) ; CHECK-NEXT: call void @omp_set_num_threads(i32 2) ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i1 [[TMP0]], false ; CHECK-NEXT: br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]] ; CHECK: 3: ; CHECK-NEXT: [[TMP4:%.*]] = call i32 @bad_use(i32 10) ; CHECK-NEXT: br label [[TMP5]] ; CHECK: 5: ; CHECK-NEXT: [[TMP6:%.*]] = call i32 @omp_get_max_threads() ; CHECK-NEXT: call void @use(i32 [[TMP6]]) ; CHECK-NEXT: ret void ; call void @omp_set_num_threads(i32 2) %2 = icmp eq i1 %0, 0 br i1 %2, label %5, label %3 3: ; preds = %1 %4 = call i32 @bad_use(i32 10) br label %5 5: ; preds = %3, %1 %6 = call i32 @omp_get_max_threads() call void @use(i32 %6) ret void } define weak void @weak_known_unique_icv(i1 %0) { ; CHECK-LABEL: define {{[^@]+}}@weak_known_unique_icv ; CHECK-SAME: (i1 [[TMP0:%.*]]) ; CHECK-NEXT: call void @omp_set_num_threads(i32 2) ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i1 [[TMP0]], false ; CHECK-NEXT: br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]] ; CHECK: 3: ; CHECK-NEXT: [[TMP4:%.*]] = call i32 @icv_free_use(i32 10) ; CHECK-NEXT: br label [[TMP5]] ; CHECK: 5: ; CHECK-NEXT: [[TMP6:%.*]] = call i32 @omp_get_max_threads() ; CHECK-NEXT: [[TMP7:%.*]] = call i32 @icv_free_use(i32 [[TMP6]]) ; CHECK-NEXT: ret void ; call void @omp_set_num_threads(i32 2) %2 = icmp eq i1 %0, 0 br i1 %2, label %5, label %3 3: ; preds = %1 %4 = call i32 @icv_free_use(i32 10) br label %5 5: ; preds = %3, %1 %6 = call i32 @omp_get_max_threads() %7 = call i32 @icv_free_use(i32 %6) ret void } define void @known_unique_icv(i1 %0) { ; CHECK-LABEL: define {{[^@]+}}@known_unique_icv ; CHECK-SAME: (i1 [[TMP0:%.*]]) ; CHECK-NEXT: call void @omp_set_num_threads(i32 2) ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i1 [[TMP0]], false ; CHECK-NEXT: br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]] ; CHECK: 3: ; CHECK-NEXT: [[TMP4:%.*]] = call i32 @icv_free_use(i32 10) ; CHECK-NEXT: br label [[TMP5]] ; CHECK: 5: ; CHECK-NEXT: [[TMP6:%.*]] = call i32 @icv_free_use(i32 2) ; CHECK-NEXT: ret void ; call void @omp_set_num_threads(i32 2) %2 = icmp eq i1 %0, 0 br i1 %2, label %5, label %3 3: ; preds = %1 %4 = call i32 @icv_free_use(i32 10) br label %5 5: ; preds = %3, %1 %6 = call i32 @omp_get_max_threads() %7 = call i32 @icv_free_use(i32 %6) ret void } define i32 @no_unique_icv(i1 %0) { ; CHECK-LABEL: define {{[^@]+}}@no_unique_icv ; CHECK-SAME: (i1 [[TMP0:%.*]]) ; CHECK-NEXT: call void @omp_set_num_threads(i32 4) ; CHECK-NEXT: br i1 [[TMP0]], label [[TMP3:%.*]], label [[TMP2:%.*]] ; CHECK: 2: ; CHECK-NEXT: call void @omp_set_num_threads(i32 2) ; CHECK-NEXT: br label [[TMP3]] ; CHECK: 3: ; CHECK-NEXT: [[TMP4:%.*]] = call i32 @omp_get_max_threads() ; CHECK-NEXT: ret i32 [[TMP4]] ; call void @omp_set_num_threads(i32 4) br i1 %0, label %3, label %2 2: ; preds = %1 call void @omp_set_num_threads(i32 2) br label %3 3: ; preds = %1, %2 %4 = call i32 @omp_get_max_threads() ret i32 %4 } define void @test2(i1 %0) { ; CHECK-LABEL: define {{[^@]+}}@test2 ; CHECK-SAME: (i1 [[TMP0:%.*]]) ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i1 [[TMP0]], false ; CHECK-NEXT: br i1 [[TMP2]], label [[TMP4:%.*]], label [[TMP3:%.*]] ; CHECK: 3: ; CHECK-NEXT: call void @omp_set_num_threads(i32 4) ; CHECK-NEXT: br label [[TMP4]] ; CHECK: 4: ; CHECK-NEXT: [[TMP5:%.*]] = call i32 @omp_get_max_threads() ; CHECK-NEXT: call void @use(i32 [[TMP5]]) ; CHECK-NEXT: ret void ; %2 = icmp eq i1 %0, 0 br i1 %2, label %4, label %3 3: ; preds = %1 call void @omp_set_num_threads(i32 4) br label %4 4: ; preds = %3, %1 %5 = call i32 @omp_get_max_threads() call void @use(i32 %5) ret void } define void @test3(i1 %0) { ; CHECK-LABEL: define {{[^@]+}}@test3 ; CHECK-SAME: (i1 [[TMP0:%.*]]) ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i1 [[TMP0]], false ; CHECK-NEXT: br i1 [[TMP2]], label [[TMP4:%.*]], label [[TMP3:%.*]] ; CHECK: 3: ; CHECK-NEXT: call void @omp_set_num_threads(i32 4) ; CHECK-NEXT: br label [[TMP4]] ; CHECK: 4: ; CHECK-NEXT: call void @weak_known_unique_icv(i1 [[TMP0]]) ; CHECK-NEXT: [[TMP5:%.*]] = call i32 @omp_get_max_threads() ; CHECK-NEXT: [[TMP6:%.*]] = call i32 @icv_free_use(i32 [[TMP5]]) ; CHECK-NEXT: ret void ; %2 = icmp eq i1 %0, 0 br i1 %2, label %4, label %3 3: ; preds = %1 call void @omp_set_num_threads(i32 4) br label %4 4: ; preds = %3, %1 call void @weak_known_unique_icv(i1 %0) %5 = call i32 @omp_get_max_threads() %6 = call i32 @icv_free_use(i32 %5) ret void } declare void @__cxa_rethrow() define i32 @maybe_throw(i1 zeroext %0) { ; CHECK-LABEL: define {{[^@]+}}@maybe_throw ; CHECK-SAME: (i1 zeroext [[TMP0:%.*]]) ; CHECK-NEXT: call void @omp_set_num_threads(i32 4) ; CHECK-NEXT: br i1 [[TMP0]], label [[TMP2:%.*]], label [[TMP3:%.*]] ; CHECK: 2: ; CHECK-NEXT: tail call void @__cxa_rethrow() ; CHECK-NEXT: unreachable ; CHECK: 3: ; CHECK-NEXT: ret i32 -1 ; call void @omp_set_num_threads(i32 4) br i1 %0, label %2, label %3 2: ; preds = %1 tail call void @__cxa_rethrow() #1 unreachable 3: ; preds = %1 ret i32 -1 } define void @test4(i1 %0) { ; CHECK-LABEL: define {{[^@]+}}@test4 ; CHECK-SAME: (i1 [[TMP0:%.*]]) ; CHECK-NEXT: call void @known_unique_icv(i1 [[TMP0]]) ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i1 [[TMP0]], false ; CHECK-NEXT: br i1 [[TMP2]], label [[TMP4:%.*]], label [[TMP3:%.*]] ; CHECK: 3: ; CHECK-NEXT: [[VAL:%.*]] = call i32 @icv_free_use(i32 10) ; CHECK-NEXT: br label [[TMP4]] ; CHECK: 4: ; CHECK-NEXT: call void @use(i32 2) ; CHECK-NEXT: [[TMP5:%.*]] = call i32 @omp_get_max_threads() ; CHECK-NEXT: [[TMP6:%.*]] = call i32 @no_unique_icv(i1 [[TMP0]]) ; CHECK-NEXT: call void @use(i32 [[TMP5]]) ; CHECK-NEXT: ret void ; call void @known_unique_icv(i1 %0) %2 = icmp eq i1 %0, 0 br i1 %2, label %4, label %3 3: ; preds = %1 %val = call i32 @icv_free_use(i32 10) br label %4 4: ; preds = %3, %1 %5 = call i32 @omp_get_max_threads() call void @use(i32 %5) %6 = call i32 @omp_get_max_threads() call i32 @no_unique_icv(i1 %0) call void @use(i32 %6) ret void } define void @test4_invoke(i1 %0) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { ; CHECK-LABEL: define {{[^@]+}}@test4_invoke ; CHECK-SAME: (i1 [[TMP0:%.*]]) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) ; CHECK-NEXT: call void @known_unique_icv(i1 [[TMP0]]) ; CHECK-NEXT: [[TMP2:%.*]] = invoke i32 @maybe_throw(i1 [[TMP0]]) ; CHECK-NEXT: to label [[CONT:%.*]] unwind label [[EXC:%.*]] ; CHECK: cont: ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i1 [[TMP0]], false ; CHECK-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]] ; CHECK: exc: ; CHECK-NEXT: [[LP:%.*]] = landingpad { i8*, i32 } ; CHECK-NEXT: filter [0 x i8*] zeroinitializer ; CHECK-NEXT: unreachable ; CHECK: 4: ; CHECK-NEXT: [[VAL:%.*]] = call i32 @icv_free_use(i32 10) ; CHECK-NEXT: br label [[TMP5]] ; CHECK: 5: ; CHECK-NEXT: call void @use(i32 2) ; CHECK-NEXT: ret void ; call void @known_unique_icv(i1 %0) invoke i32 @maybe_throw(i1 %0) to label %cont unwind label %exc cont: %3 = icmp eq i1 %0, 0 br i1 %3, label %5, label %4 exc: %lp = landingpad { i8*, i32 } filter [0 x i8*] zeroinitializer unreachable 4: ; preds = %1 %val = call i32 @icv_free_use(i32 10) br label %5 5: ; preds = %3, %1 %6 = call i32 @omp_get_max_threads() call void @use(i32 %6) ret void } define i32 @test5(i32 %0) #0 { ; CHECK-LABEL: define {{[^@]+}}@test5 ; CHECK-SAME: (i32 [[TMP0:%.*]]) ; CHECK-NEXT: call void @omp_set_num_threads(i32 4) ; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP0]], 3 ; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] ; CHECK: 3: ; CHECK-NEXT: call void @use(i32 4) ; CHECK-NEXT: br label [[TMP12:%.*]] ; CHECK: 4: ; CHECK-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[TMP0]], 0 ; CHECK-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP8:%.*]] ; CHECK: 6: ; CHECK-NEXT: [[TMP7:%.*]] = call i32 @icv_free_use(i32 [[TMP0]]) ; CHECK-NEXT: br label [[TMP15:%.*]] ; CHECK: 8: ; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP0]], 0 ; CHECK-NEXT: br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP12]] ; CHECK: 10: ; CHECK-NEXT: [[TMP11:%.*]] = call i32 @icv_free_use(i32 10) ; CHECK-NEXT: br label [[TMP15]] ; CHECK: 12: ; CHECK-NEXT: [[TMP13:%.*]] = add nsw i32 [[TMP0]], 1 ; CHECK-NEXT: [[TMP14:%.*]] = call i32 @icv_free_use(i32 [[TMP13]]) ; CHECK-NEXT: br label [[TMP15]] ; CHECK: 15: ; CHECK-NEXT: [[TMP16:%.*]] = call i32 @omp_get_max_threads() ; CHECK-NEXT: [[TMP17:%.*]] = call i32 @icv_free_use(i32 [[TMP16]]) ; CHECK-NEXT: ret i32 [[TMP17]] ; call void @omp_set_num_threads(i32 4) %2 = icmp sgt i32 %0, 3 br i1 %2, label %3, label %5 3: %4 = call i32 @omp_get_max_threads() call void @use(i32 %4) br label %13 5: %6 = icmp sgt i32 %0, 0 br i1 %6, label %7, label %9 7: %8 = call i32 @icv_free_use(i32 %0) br label %16 9: %10 = icmp eq i32 %0, 0 br i1 %10, label %11, label %13 11: %12 = call i32 @icv_free_use(i32 10) br label %16 13: %14 = add nsw i32 %0, 1 %15 = call i32 @icv_free_use(i32 %14) br label %16 16: %17 = call i32 @omp_get_max_threads() %18 = call i32 @icv_free_use(i32 %17) ret i32 %18 } define i32 @test6(i32 %0) { ; CHECK-LABEL: define {{[^@]+}}@test6 ; CHECK-SAME: (i32 [[TMP0:%.*]]) ; CHECK-NEXT: call void @omp_set_num_threads(i32 4) ; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP0]], 3 ; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] ; CHECK: 3: ; CHECK-NEXT: [[TMP4:%.*]] = call i32 @icv_free_use(i32 10) ; CHECK-NEXT: br label [[TMP16:%.*]] ; CHECK: 5: ; CHECK-NEXT: [[TMP6:%.*]] = icmp sgt i32 [[TMP0]], 0 ; CHECK-NEXT: br i1 [[TMP6]], label [[TMP7:%.*]], label [[TMP9:%.*]] ; CHECK: 7: ; CHECK-NEXT: [[TMP8:%.*]] = call i32 @icv_free_use(i32 [[TMP0]]) ; CHECK-NEXT: br label [[TMP16]] ; CHECK: 9: ; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP0]], 0 ; CHECK-NEXT: br i1 [[TMP10]], label [[TMP11:%.*]], label [[TMP13:%.*]] ; CHECK: 11: ; CHECK-NEXT: [[TMP12:%.*]] = call i32 @icv_free_use(i32 5) ; CHECK-NEXT: br label [[TMP16]] ; CHECK: 13: ; CHECK-NEXT: [[TMP14:%.*]] = add nsw i32 [[TMP0]], 1 ; CHECK-NEXT: [[TMP15:%.*]] = call i32 @icv_free_use(i32 [[TMP14]]) ; CHECK-NEXT: br label [[TMP16]] ; CHECK: 16: ; CHECK-NEXT: [[TMP17:%.*]] = call i32 @icv_free_use(i32 4) ; CHECK-NEXT: ret i32 [[TMP17]] ; call void @omp_set_num_threads(i32 4) %2 = icmp sgt i32 %0, 3 br i1 %2, label %3, label %5 3: ; preds = %1 %4 = call i32 @icv_free_use(i32 10) br label %16 5: ; preds = %1 %6 = icmp sgt i32 %0, 0 br i1 %6, label %7, label %9 7: ; preds = %5 %8 = call i32 @icv_free_use(i32 %0) br label %16 9: ; preds = %5 %10 = icmp eq i32 %0, 0 br i1 %10, label %11, label %13 11: ; preds = %9 %12 = call i32 @icv_free_use(i32 5) br label %16 13: ; preds = %9 %14 = add nsw i32 %0, 1 %15 = call i32 @icv_free_use(i32 %14) br label %16 16: ; preds = %7, %13, %11, %3 %17 = call i32 @omp_get_max_threads() %18 = call i32 @icv_free_use(i32 %17) ret i32 %18 } declare i32 @__gxx_personality_v0(...) !0 = !{!1} !1 = !{i64 2, i64 -1, i64 -1, i1 true}