|  | ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 | 
|  | ; RUN: opt < %s -passes=inline -S | FileCheck %s | 
|  | ; RUN: opt < %s -passes='cgscc(inline)' -S | FileCheck %s | 
|  |  | 
|  | %struct.a = type { i32, i32, i32, i32, i32 } | 
|  |  | 
|  | @g_var = global %struct.a { i32 1, i32 0, i32 0, i32 0, i32 0 }, align 8 | 
|  | @other_g_var = global %struct.a zeroinitializer, align 4 | 
|  |  | 
|  | define void @callee(ptr noundef byval(%struct.a) align 8 %ptr) { | 
|  | ; CHECK-LABEL: define void @callee( | 
|  | ; CHECK-SAME: ptr noundef byval([[STRUCT_A:%.*]]) align 8 [[PTR:%.*]]) { | 
|  | ; CHECK-NEXT:  entry: | 
|  | ; CHECK-NEXT:    [[VAL:%.*]] = load i32, ptr [[PTR]], align 8 | 
|  | ; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[VAL]], 0 | 
|  | ; CHECK-NEXT:    br i1 [[DOTNOT]], label [[CHECK_POINTERS_ARE_EQUAL:%.*]], label [[STORE_PTR_IN_GVAR:%.*]] | 
|  | ; CHECK:       store_ptr_in_gvar: | 
|  | ; CHECK-NEXT:    store ptr [[PTR]], ptr @other_g_var, align 8 | 
|  | ; CHECK-NEXT:    br label [[CHECK_POINTERS_ARE_EQUAL]] | 
|  | ; CHECK:       check_pointers_are_equal: | 
|  | ; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[PTR]], [[STORE_PTR_IN_GVAR]] ], [ @other_g_var, [[ENTRY:%.*]] ] | 
|  | ; CHECK-NEXT:    [[DOTNOT1:%.*]] = icmp eq ptr [[PHI]], [[PTR]] | 
|  | ; CHECK-NEXT:    br i1 [[DOTNOT1]], label [[RETURN:%.*]], label [[ABORT:%.*]] | 
|  | ; CHECK:       abort: | 
|  | ; CHECK-NEXT:    call void @abort() | 
|  | ; CHECK-NEXT:    unreachable | 
|  | ; CHECK:       return: | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | entry: | 
|  | %val = load i32, ptr %ptr, align 8 | 
|  | %.not = icmp eq i32 %val, 0 | 
|  | br i1 %.not, label %check_pointers_are_equal, label %store_ptr_in_gvar | 
|  |  | 
|  | store_ptr_in_gvar:                                ; preds = %entry | 
|  | store ptr %ptr, ptr @other_g_var, align 8 | 
|  | br label %check_pointers_are_equal | 
|  |  | 
|  | check_pointers_are_equal:                         ; preds = %store_ptr_in_gvar, %entry | 
|  | %phi = phi ptr [ %ptr, %store_ptr_in_gvar ], [ @other_g_var, %entry ] | 
|  | ; FIXME: While inlining, the following is miscompiled to i1 false, | 
|  | ; as %ptr in the phi-node is not taken into account. | 
|  | %.not1 = icmp eq ptr %phi, %ptr | 
|  | br i1 %.not1, label %return, label %abort | 
|  |  | 
|  | abort:                                            ; preds = %check_pointers_are_equal | 
|  | call void @abort() | 
|  | unreachable | 
|  |  | 
|  | return:                                           ; preds = %check_pointers_are_equal | 
|  | ret void | 
|  | } | 
|  |  | 
|  | define i32 @main() { | 
|  | ; CHECK-LABEL: define i32 @main() { | 
|  | ; CHECK-NEXT:    [[G_VAR:%.*]] = alloca [[STRUCT_A:%.*]], align 8 | 
|  | ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 20, ptr [[G_VAR]]) | 
|  | ; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[G_VAR]], ptr align 1 @g_var, i64 20, i1 false) | 
|  | ; CHECK-NEXT:    [[VAL_I:%.*]] = load i32, ptr [[G_VAR]], align 8 | 
|  | ; CHECK-NEXT:    [[DOTNOT_I:%.*]] = icmp eq i32 [[VAL_I]], 0 | 
|  | ; CHECK-NEXT:    br i1 [[DOTNOT_I]], label [[CHECK_POINTERS_ARE_EQUAL_I:%.*]], label [[STORE_PTR_IN_GVAR_I:%.*]] | 
|  | ; CHECK:       store_ptr_in_gvar.i: | 
|  | ; CHECK-NEXT:    store ptr [[G_VAR]], ptr @other_g_var, align 8 | 
|  | ; CHECK-NEXT:    br label [[CHECK_POINTERS_ARE_EQUAL_I]] | 
|  | ; CHECK:       check_pointers_are_equal.i: | 
|  | ; CHECK-NEXT:    [[PHI_I:%.*]] = phi ptr [ [[G_VAR]], [[STORE_PTR_IN_GVAR_I]] ], [ @other_g_var, [[TMP0:%.*]] ] | 
|  | ; CHECK-NEXT:    call void @abort() | 
|  | ; CHECK-NEXT:    unreachable | 
|  | ; CHECK:       callee.exit: | 
|  | ; CHECK-NEXT:    ret i32 0 | 
|  | ; | 
|  | call void @callee(ptr noundef byval(%struct.a) align 8 @g_var) | 
|  | ret i32 0 | 
|  | } | 
|  |  | 
|  | declare void @abort() |