| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals | |
| ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT | |
| ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC | |
| ; | |
| target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" | |
| %struct.S = type { i32, double, ptr, i32 } | |
| ; struct S { | |
| ; int a; | |
| ; double b; | |
| ; struct S* c; | |
| ; int written; | |
| ; }; | |
| ; | |
| ; static const struct S GlobalS = {42, 3.14, 0}; | |
| ; | |
| ; int testOneFieldGlobalS() { | |
| ; int r = 0; | |
| ; if (GlobalS.a != 42) | |
| ; r += 1; | |
| ; if (GlobalS.b == 3.14) | |
| ; r += 2; | |
| ; if (GlobalS.c) | |
| ; r += 4; | |
| ; return r; | |
| ; } | |
| ; | |
| @GlobalS = internal constant %struct.S { i32 42, double 3.140000e+00, ptr null, i32 0 }, align 8 | |
| declare void @harmless_use(ptr nocapture readonly) nofree norecurse nosync nounwind readnone willreturn nocallback | |
| ;. | |
| ; CHECK: @GlobalS = internal constant %struct.S { i32 42, double 3.140000e+00, ptr null, i32 0 }, align 8 | |
| ;. | |
| define i32 @testOneFieldGlobalS(i32 %cmpx) { | |
| ; CHECK: Function Attrs: mustprogress norecurse nounwind willreturn memory(none) | |
| ; CHECK-LABEL: define {{[^@]+}}@testOneFieldGlobalS | |
| ; CHECK-SAME: (i32 [[CMPX:%.*]]) #[[ATTR1:[0-9]+]] { | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: [[RMW:%.*]] = atomicrmw add ptr getelementptr inbounds ([[STRUCT_S:%.*]], ptr @GlobalS, i32 0, i32 3), i32 1 monotonic, align 4 | |
| ; CHECK-NEXT: [[CXI:%.*]] = cmpxchg ptr getelementptr inbounds ([[STRUCT_S]], ptr @GlobalS, i32 0, i32 3), i32 [[CMPX]], i32 7 acq_rel monotonic, align 4 | |
| ; CHECK-NEXT: br label [[IF_END:%.*]] | |
| ; CHECK: if.then: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: if.end: | |
| ; CHECK-NEXT: br label [[IF_THEN2:%.*]] | |
| ; CHECK: if.then2: | |
| ; CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 0, 2 | |
| ; CHECK-NEXT: br label [[IF_END4:%.*]] | |
| ; CHECK: if.end4: | |
| ; CHECK-NEXT: br label [[IF_END7:%.*]] | |
| ; CHECK: if.then5: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: if.end7: | |
| ; CHECK-NEXT: ret i32 2 | |
| ; | |
| entry: | |
| %i = load i32, ptr @GlobalS, align 8 | |
| call void @harmless_use(ptr @GlobalS) | |
| %rmw = atomicrmw add ptr getelementptr inbounds (%struct.S, ptr @GlobalS, i32 0, i32 3), i32 1 monotonic, align 4 | |
| %cxi = cmpxchg ptr getelementptr inbounds (%struct.S, ptr @GlobalS, i32 0, i32 3), i32 %cmpx, i32 7 acq_rel monotonic | |
| %cmp = icmp ne i32 %i, 42 | |
| br i1 %cmp, label %if.then, label %if.end | |
| if.then: ; preds = %entry | |
| %add = add nsw i32 0, 1 | |
| br label %if.end | |
| if.end: ; preds = %if.then, %entry | |
| %r.0 = phi i32 [ %add, %if.then ], [ 0, %entry ] | |
| %i1 = load double, ptr getelementptr inbounds (%struct.S, ptr @GlobalS, i32 0, i32 1), align 8 | |
| %cmp1 = fcmp oeq double %i1, 3.140000e+00 | |
| br i1 %cmp1, label %if.then2, label %if.end4 | |
| if.then2: ; preds = %if.end | |
| %add3 = add nsw i32 %r.0, 2 | |
| br label %if.end4 | |
| if.end4: ; preds = %if.then2, %if.end | |
| %r.1 = phi i32 [ %add3, %if.then2 ], [ %r.0, %if.end ] | |
| %i2 = load ptr, ptr getelementptr inbounds (%struct.S, ptr @GlobalS, i32 0, i32 2), align 8 | |
| %tobool = icmp ne ptr %i2, null | |
| br i1 %tobool, label %if.then5, label %if.end7 | |
| if.then5: ; preds = %if.end4 | |
| %add6 = add nsw i32 %r.1, 4 | |
| br label %if.end7 | |
| if.end7: ; preds = %if.then5, %if.end4 | |
| %r.2 = phi i32 [ %add6, %if.then5 ], [ %r.1, %if.end4 ] | |
| ret i32 %r.2 | |
| } | |
| define i32 @testOneFieldGlobalS_type_mismatch() { | |
| ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) | |
| ; CHECK-LABEL: define {{[^@]+}}@testOneFieldGlobalS_type_mismatch | |
| ; CHECK-SAME: () #[[ATTR2:[0-9]+]] { | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[IF_THEN:%.*]] | |
| ; CHECK: if.then: | |
| ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 0, 1 | |
| ; CHECK-NEXT: br label [[IF_END:%.*]] | |
| ; CHECK: if.end: | |
| ; CHECK-NEXT: br label [[IF_END4:%.*]] | |
| ; CHECK: if.then2: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: if.end4: | |
| ; CHECK-NEXT: br label [[IF_END7:%.*]] | |
| ; CHECK: if.then5: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: if.end7: | |
| ; CHECK-NEXT: ret i32 1 | |
| ; | |
| entry: | |
| %i = load double, ptr @GlobalS, align 8 | |
| %ic = fptosi double %i to i32 | |
| %cmp = icmp ne i32 %ic, 42 | |
| br i1 %cmp, label %if.then, label %if.end | |
| if.then: ; preds = %entry | |
| %add = add nsw i32 0, 1 | |
| br label %if.end | |
| if.end: ; preds = %if.then, %entry | |
| %r.0 = phi i32 [ %add, %if.then ], [ 0, %entry ] | |
| %i1 = load i64, ptr getelementptr inbounds (%struct.S, ptr @GlobalS, i32 0, i32 1), align 8 | |
| %i1c = sitofp i64 %i1 to double | |
| %cmp1 = fcmp oeq double %i1c, 3.140000e+00 | |
| br i1 %cmp1, label %if.then2, label %if.end4 | |
| if.then2: ; preds = %if.end | |
| %add3 = add nsw i32 %r.0, 2 | |
| br label %if.end4 | |
| if.end4: ; preds = %if.then2, %if.end | |
| %r.1 = phi i32 [ %add3, %if.then2 ], [ %r.0, %if.end ] | |
| %i2 = load i64, ptr getelementptr inbounds (%struct.S, ptr @GlobalS, i32 0, i32 2), align 8 | |
| %i2c = inttoptr i64 %i2 to ptr | |
| %tobool = icmp ne ptr %i2c, null | |
| br i1 %tobool, label %if.then5, label %if.end7 | |
| if.then5: ; preds = %if.end4 | |
| %add6 = add nsw i32 %r.1, 4 | |
| br label %if.end7 | |
| if.end7: ; preds = %if.then5, %if.end4 | |
| %r.2 = phi i32 [ %add6, %if.then5 ], [ %r.1, %if.end4 ] | |
| ret i32 %r.2 | |
| } | |
| define i32 @testOneFieldGlobalS_byte_offset_wrong() { | |
| ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) | |
| ; CHECK-LABEL: define {{[^@]+}}@testOneFieldGlobalS_byte_offset_wrong | |
| ; CHECK-SAME: () #[[ATTR2]] { | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[IF_THEN:%.*]] | |
| ; CHECK: if.then: | |
| ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 0, 1 | |
| ; CHECK-NEXT: br label [[IF_END:%.*]] | |
| ; CHECK: if.end: | |
| ; CHECK-NEXT: [[I1:%.*]] = load double, ptr getelementptr (double, ptr @GlobalS, i32 3), align 8 | |
| ; CHECK-NEXT: [[CMP1:%.*]] = fcmp oeq double [[I1]], 3.140000e+00 | |
| ; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END4:%.*]] | |
| ; CHECK: if.then2: | |
| ; CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 1, 2 | |
| ; CHECK-NEXT: br label [[IF_END4]] | |
| ; CHECK: if.end4: | |
| ; CHECK-NEXT: [[R_1:%.*]] = phi i32 [ [[ADD3]], [[IF_THEN2]] ], [ 1, [[IF_END]] ] | |
| ; CHECK-NEXT: br label [[IF_END7:%.*]] | |
| ; CHECK: if.then5: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: if.end7: | |
| ; CHECK-NEXT: ret i32 [[R_1]] | |
| ; | |
| entry: | |
| %i = load i32, ptr getelementptr (i32, ptr @GlobalS, i32 1), align 8 | |
| %cmp = icmp ne i32 %i, 42 | |
| br i1 %cmp, label %if.then, label %if.end | |
| if.then: ; preds = %entry | |
| %add = add nsw i32 0, 1 | |
| br label %if.end | |
| if.end: ; preds = %if.then, %entry | |
| %r.0 = phi i32 [ %add, %if.then ], [ 0, %entry ] | |
| %i1 = load double, ptr getelementptr (double, ptr @GlobalS, i32 3), align 8 | |
| %cmp1 = fcmp oeq double %i1, 3.140000e+00 | |
| br i1 %cmp1, label %if.then2, label %if.end4 | |
| if.then2: ; preds = %if.end | |
| %add3 = add nsw i32 %r.0, 2 | |
| br label %if.end4 | |
| if.end4: ; preds = %if.then2, %if.end | |
| %r.1 = phi i32 [ %add3, %if.then2 ], [ %r.0, %if.end ] | |
| %i2 = load ptr, ptr getelementptr (ptr, ptr @GlobalS, i32 2), align 8 | |
| %tobool = icmp ne ptr %i2, null | |
| br i1 %tobool, label %if.then5, label %if.end7 | |
| if.then5: ; preds = %if.end4 | |
| %add6 = add nsw i32 %r.1, 4 | |
| br label %if.end7 | |
| if.end7: ; preds = %if.then5, %if.end4 | |
| %r.2 = phi i32 [ %add6, %if.then5 ], [ %r.1, %if.end4 ] | |
| ret i32 %r.2 | |
| } | |
| ;. | |
| ; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree norecurse nosync nounwind willreturn memory(none) } | |
| ; CHECK: attributes #[[ATTR1]] = { mustprogress norecurse nounwind willreturn memory(none) } | |
| ; CHECK: attributes #[[ATTR2]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) } | |
| ;. | |
| ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: | |
| ; CGSCC: {{.*}} | |
| ; TUNIT: {{.*}} |