|
| 1 | +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 |
| 2 | +; RUN: opt < %s -passes=inline -S | FileCheck %s |
| 3 | +; RUN: opt < %s -passes='cgscc(inline)' -S | FileCheck %s |
| 4 | + |
| 5 | +%struct.a = type { i32, i32, i32, i32, i32 } |
| 6 | + |
| 7 | +@g_var = global %struct.a { i32 1, i32 0, i32 0, i32 0, i32 0 }, align 8 |
| 8 | +@other_g_var = global %struct.a zeroinitializer, align 4 |
| 9 | + |
| 10 | +define void @callee(ptr noundef byval(%struct.a) align 8 %ptr) { |
| 11 | +; CHECK-LABEL: define void @callee( |
| 12 | +; CHECK-SAME: ptr noundef byval([[STRUCT_A:%.*]]) align 8 [[PTR:%.*]]) { |
| 13 | +; CHECK-NEXT: entry: |
| 14 | +; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[PTR]], align 8 |
| 15 | +; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[VAL]], 0 |
| 16 | +; CHECK-NEXT: br i1 [[DOTNOT]], label [[CHECK_POINTERS_ARE_EQUAL:%.*]], label [[STORE_PTR_IN_GVAR:%.*]] |
| 17 | +; CHECK: store_ptr_in_gvar: |
| 18 | +; CHECK-NEXT: store ptr [[PTR]], ptr @other_g_var, align 8 |
| 19 | +; CHECK-NEXT: br label [[CHECK_POINTERS_ARE_EQUAL]] |
| 20 | +; CHECK: check_pointers_are_equal: |
| 21 | +; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[PTR]], [[STORE_PTR_IN_GVAR]] ], [ @other_g_var, [[ENTRY:%.*]] ] |
| 22 | +; CHECK-NEXT: [[DOTNOT1:%.*]] = icmp eq ptr [[PHI]], [[PTR]] |
| 23 | +; CHECK-NEXT: br i1 [[DOTNOT1]], label [[RETURN:%.*]], label [[ABORT:%.*]] |
| 24 | +; CHECK: abort: |
| 25 | +; CHECK-NEXT: call void @abort() |
| 26 | +; CHECK-NEXT: unreachable |
| 27 | +; CHECK: return: |
| 28 | +; CHECK-NEXT: ret void |
| 29 | +; |
| 30 | +entry: |
| 31 | + %val = load i32, ptr %ptr, align 8 |
| 32 | + %.not = icmp eq i32 %val, 0 |
| 33 | + br i1 %.not, label %check_pointers_are_equal, label %store_ptr_in_gvar |
| 34 | + |
| 35 | +store_ptr_in_gvar: ; preds = %entry |
| 36 | + store ptr %ptr, ptr @other_g_var, align 8 |
| 37 | + br label %check_pointers_are_equal |
| 38 | + |
| 39 | +check_pointers_are_equal: ; preds = %store_ptr_in_gvar, %entry |
| 40 | + %phi = phi ptr [ %ptr, %store_ptr_in_gvar ], [ @other_g_var, %entry ] |
| 41 | +; FIXME: While inlining, the following is miscompiled to i1 false, |
| 42 | +; as %ptr in the phi-node is not taken into account. |
| 43 | + %.not1 = icmp eq ptr %phi, %ptr |
| 44 | + br i1 %.not1, label %return, label %abort |
| 45 | + |
| 46 | +abort: ; preds = %check_pointers_are_equal |
| 47 | + call void @abort() |
| 48 | + unreachable |
| 49 | + |
| 50 | +return: ; preds = %check_pointers_are_equal |
| 51 | + ret void |
| 52 | +} |
| 53 | + |
| 54 | +define i32 @main() { |
| 55 | +; CHECK-LABEL: define i32 @main() { |
| 56 | +; CHECK-NEXT: [[G_VAR:%.*]] = alloca [[STRUCT_A:%.*]], align 8 |
| 57 | +; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 20, ptr [[G_VAR]]) |
| 58 | +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[G_VAR]], ptr align 1 @g_var, i64 20, i1 false) |
| 59 | +; CHECK-NEXT: [[VAL_I:%.*]] = load i32, ptr [[G_VAR]], align 8 |
| 60 | +; CHECK-NEXT: [[DOTNOT_I:%.*]] = icmp eq i32 [[VAL_I]], 0 |
| 61 | +; CHECK-NEXT: br i1 [[DOTNOT_I]], label [[CHECK_POINTERS_ARE_EQUAL_I:%.*]], label [[STORE_PTR_IN_GVAR_I:%.*]] |
| 62 | +; CHECK: store_ptr_in_gvar.i: |
| 63 | +; CHECK-NEXT: store ptr [[G_VAR]], ptr @other_g_var, align 8 |
| 64 | +; CHECK-NEXT: br label [[CHECK_POINTERS_ARE_EQUAL_I]] |
| 65 | +; CHECK: check_pointers_are_equal.i: |
| 66 | +; CHECK-NEXT: [[PHI_I:%.*]] = phi ptr [ [[G_VAR]], [[STORE_PTR_IN_GVAR_I]] ], [ @other_g_var, [[TMP0:%.*]] ] |
| 67 | +; CHECK-NEXT: call void @abort() |
| 68 | +; CHECK-NEXT: unreachable |
| 69 | +; CHECK: callee.exit: |
| 70 | +; CHECK-NEXT: ret i32 0 |
| 71 | +; |
| 72 | + call void @callee(ptr noundef byval(%struct.a) align 8 @g_var) |
| 73 | + ret i32 0 |
| 74 | +} |
| 75 | + |
| 76 | +declare void @abort() |
0 commit comments