1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals 2; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT 3; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC 4; 5target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 6 7%struct.S = type { i32, double, ptr, i32 } 8 9; struct S { 10; int a; 11; double b; 12; struct S* c; 13; int written; 14; }; 15; 16; static const struct S GlobalS = {42, 3.14, 0}; 17; 18; int testOneFieldGlobalS() { 19; int r = 0; 20; if (GlobalS.a != 42) 21; r += 1; 22; if (GlobalS.b == 3.14) 23; r += 2; 24; if (GlobalS.c) 25; r += 4; 26; return r; 27; } 28; 29@GlobalS = internal constant %struct.S { i32 42, double 3.140000e+00, ptr null, i32 0 }, align 8 30 31declare void @harmless_use(ptr nocapture readonly) nofree norecurse nosync nounwind readnone willreturn nocallback 32 33;. 34; CHECK: @GlobalS = internal constant %struct.S { i32 42, double 3.140000e+00, ptr null, i32 0 }, align 8 35;. 36define i32 @testOneFieldGlobalS(i32 %cmpx) { 37; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none) 38; CHECK-LABEL: define {{[^@]+}}@testOneFieldGlobalS 39; CHECK-SAME: (i32 [[CMPX:%.*]]) #[[ATTR1:[0-9]+]] { 40; CHECK-NEXT: entry: 41; CHECK-NEXT: [[RMW:%.*]] = atomicrmw add ptr getelementptr inbounds ([[STRUCT_S:%.*]], ptr @GlobalS, i32 0, i32 3), i32 1 monotonic, align 4 42; CHECK-NEXT: [[CXI:%.*]] = cmpxchg ptr getelementptr inbounds ([[STRUCT_S]], ptr @GlobalS, i32 0, i32 3), i32 [[CMPX]], i32 7 acq_rel monotonic, align 4 43; CHECK-NEXT: br label [[IF_END:%.*]] 44; CHECK: if.then: 45; CHECK-NEXT: unreachable 46; CHECK: if.end: 47; CHECK-NEXT: br label [[IF_THEN2:%.*]] 48; CHECK: if.then2: 49; CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 0, 2 50; CHECK-NEXT: br label [[IF_END4:%.*]] 51; CHECK: if.end4: 52; CHECK-NEXT: br label [[IF_END7:%.*]] 53; CHECK: if.then5: 54; CHECK-NEXT: unreachable 55; CHECK: if.end7: 56; CHECK-NEXT: ret i32 2 57; 58entry: 59 %i = load i32, ptr @GlobalS, align 8 60 call void @harmless_use(ptr @GlobalS) 61 %rmw = atomicrmw add ptr getelementptr inbounds (%struct.S, ptr @GlobalS, i32 0, i32 3), i32 1 monotonic, align 4 62 %cxi = cmpxchg ptr getelementptr inbounds (%struct.S, ptr @GlobalS, i32 0, i32 3), i32 %cmpx, i32 7 acq_rel monotonic 63 %cmp = icmp ne i32 %i, 42 64 br i1 %cmp, label %if.then, label %if.end 65 66if.then: ; preds = %entry 67 %add = add nsw i32 0, 1 68 br label %if.end 69 70if.end: ; preds = %if.then, %entry 71 %r.0 = phi i32 [ %add, %if.then ], [ 0, %entry ] 72 %i1 = load double, ptr getelementptr inbounds (%struct.S, ptr @GlobalS, i32 0, i32 1), align 8 73 %cmp1 = fcmp oeq double %i1, 3.140000e+00 74 br i1 %cmp1, label %if.then2, label %if.end4 75 76if.then2: ; preds = %if.end 77 %add3 = add nsw i32 %r.0, 2 78 br label %if.end4 79 80if.end4: ; preds = %if.then2, %if.end 81 %r.1 = phi i32 [ %add3, %if.then2 ], [ %r.0, %if.end ] 82 %i2 = load ptr, ptr getelementptr inbounds (%struct.S, ptr @GlobalS, i32 0, i32 2), align 8 83 %tobool = icmp ne ptr %i2, null 84 br i1 %tobool, label %if.then5, label %if.end7 85 86if.then5: ; preds = %if.end4 87 %add6 = add nsw i32 %r.1, 4 88 br label %if.end7 89 90if.end7: ; preds = %if.then5, %if.end4 91 %r.2 = phi i32 [ %add6, %if.then5 ], [ %r.1, %if.end4 ] 92 ret i32 %r.2 93} 94 95define i32 @testOneFieldGlobalS_type_mismatch() { 96; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 97; CHECK-LABEL: define {{[^@]+}}@testOneFieldGlobalS_type_mismatch 98; CHECK-SAME: () #[[ATTR2:[0-9]+]] { 99; CHECK-NEXT: entry: 100; CHECK-NEXT: br label [[IF_THEN:%.*]] 101; CHECK: if.then: 102; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 0, 1 103; CHECK-NEXT: br label [[IF_END:%.*]] 104; CHECK: if.end: 105; CHECK-NEXT: br label [[IF_END4:%.*]] 106; CHECK: if.then2: 107; CHECK-NEXT: unreachable 108; CHECK: if.end4: 109; CHECK-NEXT: br label [[IF_END7:%.*]] 110; CHECK: if.then5: 111; CHECK-NEXT: unreachable 112; CHECK: if.end7: 113; CHECK-NEXT: ret i32 1 114; 115entry: 116 %i = load double, ptr @GlobalS, align 8 117 %ic = fptosi double %i to i32 118 %cmp = icmp ne i32 %ic, 42 119 br i1 %cmp, label %if.then, label %if.end 120 121if.then: ; preds = %entry 122 %add = add nsw i32 0, 1 123 br label %if.end 124 125if.end: ; preds = %if.then, %entry 126 %r.0 = phi i32 [ %add, %if.then ], [ 0, %entry ] 127 %i1 = load i64, ptr getelementptr inbounds (%struct.S, ptr @GlobalS, i32 0, i32 1), align 8 128 %i1c = sitofp i64 %i1 to double 129 %cmp1 = fcmp oeq double %i1c, 3.140000e+00 130 br i1 %cmp1, label %if.then2, label %if.end4 131 132if.then2: ; preds = %if.end 133 %add3 = add nsw i32 %r.0, 2 134 br label %if.end4 135 136if.end4: ; preds = %if.then2, %if.end 137 %r.1 = phi i32 [ %add3, %if.then2 ], [ %r.0, %if.end ] 138 %i2 = load i64, ptr getelementptr inbounds (%struct.S, ptr @GlobalS, i32 0, i32 2), align 8 139 %i2c = inttoptr i64 %i2 to ptr 140 %tobool = icmp ne ptr %i2c, null 141 br i1 %tobool, label %if.then5, label %if.end7 142 143if.then5: ; preds = %if.end4 144 %add6 = add nsw i32 %r.1, 4 145 br label %if.end7 146 147if.end7: ; preds = %if.then5, %if.end4 148 %r.2 = phi i32 [ %add6, %if.then5 ], [ %r.1, %if.end4 ] 149 ret i32 %r.2 150} 151 152define i32 @testOneFieldGlobalS_byte_offset_wrong() { 153; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 154; CHECK-LABEL: define {{[^@]+}}@testOneFieldGlobalS_byte_offset_wrong 155; CHECK-SAME: () #[[ATTR2]] { 156; CHECK-NEXT: entry: 157; CHECK-NEXT: br label [[IF_THEN:%.*]] 158; CHECK: if.then: 159; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 0, 1 160; CHECK-NEXT: br label [[IF_END:%.*]] 161; CHECK: if.end: 162; CHECK-NEXT: [[I1:%.*]] = load double, ptr getelementptr (double, ptr @GlobalS, i32 3), align 8 163; CHECK-NEXT: [[CMP1:%.*]] = fcmp oeq double [[I1]], 3.140000e+00 164; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END4:%.*]] 165; CHECK: if.then2: 166; CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 1, 2 167; CHECK-NEXT: br label [[IF_END4]] 168; CHECK: if.end4: 169; CHECK-NEXT: [[R_1:%.*]] = phi i32 [ [[ADD3]], [[IF_THEN2]] ], [ 1, [[IF_END]] ] 170; CHECK-NEXT: br label [[IF_END7:%.*]] 171; CHECK: if.then5: 172; CHECK-NEXT: unreachable 173; CHECK: if.end7: 174; CHECK-NEXT: ret i32 [[R_1]] 175; 176entry: 177 %i = load i32, ptr getelementptr (i32, ptr @GlobalS, i32 1), align 8 178 %cmp = icmp ne i32 %i, 42 179 br i1 %cmp, label %if.then, label %if.end 180 181if.then: ; preds = %entry 182 %add = add nsw i32 0, 1 183 br label %if.end 184 185if.end: ; preds = %if.then, %entry 186 %r.0 = phi i32 [ %add, %if.then ], [ 0, %entry ] 187 %i1 = load double, ptr getelementptr (double, ptr @GlobalS, i32 3), align 8 188 %cmp1 = fcmp oeq double %i1, 3.140000e+00 189 br i1 %cmp1, label %if.then2, label %if.end4 190 191if.then2: ; preds = %if.end 192 %add3 = add nsw i32 %r.0, 2 193 br label %if.end4 194 195if.end4: ; preds = %if.then2, %if.end 196 %r.1 = phi i32 [ %add3, %if.then2 ], [ %r.0, %if.end ] 197 %i2 = load ptr, ptr getelementptr (ptr, ptr @GlobalS, i32 2), align 8 198 %tobool = icmp ne ptr %i2, null 199 br i1 %tobool, label %if.then5, label %if.end7 200 201if.then5: ; preds = %if.end4 202 %add6 = add nsw i32 %r.1, 4 203 br label %if.end7 204 205if.end7: ; preds = %if.then5, %if.end4 206 %r.2 = phi i32 [ %add6, %if.then5 ], [ %r.1, %if.end4 ] 207 ret i32 %r.2 208} 209;. 210; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree norecurse nosync nounwind willreturn memory(none) } 211; CHECK: attributes #[[ATTR1]] = { mustprogress nofree norecurse nounwind willreturn memory(none) } 212; CHECK: attributes #[[ATTR2]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) } 213;. 214;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: 215; CGSCC: {{.*}} 216; TUNIT: {{.*}} 217