284 lines · c
1// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 62// RUN: %clang_cc1 -triple s390x-linux-gnu -O1 -emit-llvm %s -o - | FileCheck %s3//4// Test GNU atomic builtins for __int128 aligned to 16 bytes, which should be5// expanded to LLVM I/R by the front end.6 7#include <stdatomic.h>8#include <stdint.h>9 10__int128 Ptr __attribute__((aligned(16)));11__int128 Ret __attribute__((aligned(16)));12__int128 Val __attribute__((aligned(16)));13__int128 Exp __attribute__((aligned(16)));14__int128 Des __attribute__((aligned(16)));15 16// CHECK-LABEL: define dso_local void @f1(17// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {18// CHECK-NEXT: [[ENTRY:.*:]]19// CHECK-NEXT: [[TMP0:%.*]] = load atomic i128, ptr @Ptr seq_cst, align 1620// CHECK-NEXT: store i128 [[TMP0]], ptr [[AGG_RESULT]], align 8, !tbaa [[__INT128_TBAA6:![0-9]+]]21// CHECK-NEXT: ret void22//23__int128 f1() {24 return __atomic_load_n(&Ptr, memory_order_seq_cst);25}26 27// CHECK-LABEL: define dso_local void @f2(28// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]]) local_unnamed_addr #[[ATTR0]] {29// CHECK-NEXT: [[ENTRY:.*:]]30// CHECK-NEXT: [[TMP0:%.*]] = load atomic i128, ptr @Ptr seq_cst, align 1631// CHECK-NEXT: store i128 [[TMP0]], ptr @Ret, align 1632// CHECK-NEXT: store i128 [[TMP0]], ptr [[AGG_RESULT]], align 8, !tbaa [[__INT128_TBAA6]]33// CHECK-NEXT: ret void34//35__int128 f2() {36 __atomic_load(&Ptr, &Ret, memory_order_seq_cst);37 return Ret;38}39 40// CHECK-LABEL: define dso_local void @f3(41// CHECK-SAME: ) local_unnamed_addr #[[ATTR1:[0-9]+]] {42// CHECK-NEXT: [[ENTRY:.*:]]43// CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 16, !tbaa [[__INT128_TBAA6]]44// CHECK-NEXT: store atomic i128 [[TMP0]], ptr @Ptr seq_cst, align 1645// CHECK-NEXT: ret void46//47void f3() {48 __atomic_store_n(&Ptr, Val, memory_order_seq_cst);49}50 51// CHECK-LABEL: define dso_local void @f4(52// CHECK-SAME: ) local_unnamed_addr #[[ATTR1]] {53// CHECK-NEXT: [[ENTRY:.*:]]54// CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 1655// CHECK-NEXT: store atomic i128 [[TMP0]], ptr @Ptr seq_cst, align 1656// CHECK-NEXT: ret void57//58void f4() {59 __atomic_store(&Ptr, &Val, memory_order_seq_cst);60}61 62// CHECK-LABEL: define dso_local void @f5(63// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]]) local_unnamed_addr #[[ATTR0]] {64// CHECK-NEXT: [[ENTRY:.*:]]65// CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 16, !tbaa [[__INT128_TBAA6]]66// CHECK-NEXT: [[TMP1:%.*]] = atomicrmw xchg ptr @Ptr, i128 [[TMP0]] seq_cst, align 1667// CHECK-NEXT: store i128 [[TMP1]], ptr [[AGG_RESULT]], align 8, !tbaa [[__INT128_TBAA6]]68// CHECK-NEXT: ret void69//70__int128 f5() {71 return __atomic_exchange_n(&Ptr, Val, memory_order_seq_cst);72}73 74// CHECK-LABEL: define dso_local void @f6(75// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]]) local_unnamed_addr #[[ATTR0]] {76// CHECK-NEXT: [[ENTRY:.*:]]77// CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 1678// CHECK-NEXT: [[TMP1:%.*]] = atomicrmw xchg ptr @Ptr, i128 [[TMP0]] seq_cst, align 1679// CHECK-NEXT: store i128 [[TMP1]], ptr @Ret, align 1680// CHECK-NEXT: store i128 [[TMP1]], ptr [[AGG_RESULT]], align 8, !tbaa [[__INT128_TBAA6]]81// CHECK-NEXT: ret void82//83__int128 f6() {84 __atomic_exchange(&Ptr, &Val, &Ret, memory_order_seq_cst);85 return Ret;86}87 88// CHECK-LABEL: define dso_local noundef zeroext i1 @f7(89// CHECK-SAME: ) local_unnamed_addr #[[ATTR1]] {90// CHECK-NEXT: [[ENTRY:.*:]]91// CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Des, align 16, !tbaa [[__INT128_TBAA6]]92// CHECK-NEXT: [[TMP1:%.*]] = load i128, ptr @Exp, align 1693// CHECK-NEXT: [[TMP2:%.*]] = cmpxchg ptr @Ptr, i128 [[TMP1]], i128 [[TMP0]] seq_cst seq_cst, align 1694// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i128, i1 } [[TMP2]], 195// CHECK-NEXT: br i1 [[TMP3]], label %[[CMPXCHG_CONTINUE:.*]], label %[[CMPXCHG_STORE_EXPECTED:.*]]96// CHECK: [[CMPXCHG_STORE_EXPECTED]]:97// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i128, i1 } [[TMP2]], 098// CHECK-NEXT: store i128 [[TMP4]], ptr @Exp, align 1699// CHECK-NEXT: br label %[[CMPXCHG_CONTINUE]]100// CHECK: [[CMPXCHG_CONTINUE]]:101// CHECK-NEXT: ret i1 [[TMP3]]102//103_Bool f7() {104 return __atomic_compare_exchange_n(&Ptr, &Exp, Des, 0,105 memory_order_seq_cst, memory_order_seq_cst);106}107 108// CHECK-LABEL: define dso_local noundef zeroext i1 @f8(109// CHECK-SAME: ) local_unnamed_addr #[[ATTR1]] {110// CHECK-NEXT: [[ENTRY:.*:]]111// CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Exp, align 16112// CHECK-NEXT: [[TMP1:%.*]] = load i128, ptr @Des, align 16113// CHECK-NEXT: [[TMP2:%.*]] = cmpxchg ptr @Ptr, i128 [[TMP0]], i128 [[TMP1]] seq_cst seq_cst, align 16114// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i128, i1 } [[TMP2]], 1115// CHECK-NEXT: br i1 [[TMP3]], label %[[CMPXCHG_CONTINUE:.*]], label %[[CMPXCHG_STORE_EXPECTED:.*]]116// CHECK: [[CMPXCHG_STORE_EXPECTED]]:117// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i128, i1 } [[TMP2]], 0118// CHECK-NEXT: store i128 [[TMP4]], ptr @Exp, align 16119// CHECK-NEXT: br label %[[CMPXCHG_CONTINUE]]120// CHECK: [[CMPXCHG_CONTINUE]]:121// CHECK-NEXT: ret i1 [[TMP3]]122//123_Bool f8() {124 return __atomic_compare_exchange(&Ptr, &Exp, &Des, 0,125 memory_order_seq_cst, memory_order_seq_cst);126}127 128// CHECK-LABEL: define dso_local void @f9(129// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]]) local_unnamed_addr #[[ATTR0]] {130// CHECK-NEXT: [[ENTRY:.*:]]131// CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 16, !tbaa [[__INT128_TBAA6]]132// CHECK-NEXT: [[TMP1:%.*]] = atomicrmw add ptr @Ptr, i128 [[TMP0]] seq_cst, align 16133// CHECK-NEXT: [[TMP2:%.*]] = add i128 [[TMP1]], [[TMP0]]134// CHECK-NEXT: store i128 [[TMP2]], ptr [[AGG_RESULT]], align 8, !tbaa [[__INT128_TBAA6]]135// CHECK-NEXT: ret void136//137__int128 f9() {138 return __atomic_add_fetch(&Ptr, Val, memory_order_seq_cst);139}140 141// CHECK-LABEL: define dso_local void @f10(142// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]]) local_unnamed_addr #[[ATTR0]] {143// CHECK-NEXT: [[ENTRY:.*:]]144// CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 16, !tbaa [[__INT128_TBAA6]]145// CHECK-NEXT: [[TMP1:%.*]] = atomicrmw sub ptr @Ptr, i128 [[TMP0]] seq_cst, align 16146// CHECK-NEXT: [[TMP2:%.*]] = sub i128 [[TMP1]], [[TMP0]]147// CHECK-NEXT: store i128 [[TMP2]], ptr [[AGG_RESULT]], align 8, !tbaa [[__INT128_TBAA6]]148// CHECK-NEXT: ret void149//150__int128 f10() {151 return __atomic_sub_fetch(&Ptr, Val, memory_order_seq_cst);152}153 154// CHECK-LABEL: define dso_local void @f11(155// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]]) local_unnamed_addr #[[ATTR0]] {156// CHECK-NEXT: [[ENTRY:.*:]]157// CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 16, !tbaa [[__INT128_TBAA6]]158// CHECK-NEXT: [[TMP1:%.*]] = atomicrmw and ptr @Ptr, i128 [[TMP0]] seq_cst, align 16159// CHECK-NEXT: [[TMP2:%.*]] = and i128 [[TMP1]], [[TMP0]]160// CHECK-NEXT: store i128 [[TMP2]], ptr [[AGG_RESULT]], align 8, !tbaa [[__INT128_TBAA6]]161// CHECK-NEXT: ret void162//163__int128 f11() {164 return __atomic_and_fetch(&Ptr, Val, memory_order_seq_cst);165}166 167// CHECK-LABEL: define dso_local void @f12(168// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]]) local_unnamed_addr #[[ATTR0]] {169// CHECK-NEXT: [[ENTRY:.*:]]170// CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 16, !tbaa [[__INT128_TBAA6]]171// CHECK-NEXT: [[TMP1:%.*]] = atomicrmw xor ptr @Ptr, i128 [[TMP0]] seq_cst, align 16172// CHECK-NEXT: [[TMP2:%.*]] = xor i128 [[TMP1]], [[TMP0]]173// CHECK-NEXT: store i128 [[TMP2]], ptr [[AGG_RESULT]], align 8, !tbaa [[__INT128_TBAA6]]174// CHECK-NEXT: ret void175//176__int128 f12() {177 return __atomic_xor_fetch(&Ptr, Val, memory_order_seq_cst);178}179 180// CHECK-LABEL: define dso_local void @f13(181// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]]) local_unnamed_addr #[[ATTR0]] {182// CHECK-NEXT: [[ENTRY:.*:]]183// CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 16, !tbaa [[__INT128_TBAA6]]184// CHECK-NEXT: [[TMP1:%.*]] = atomicrmw or ptr @Ptr, i128 [[TMP0]] seq_cst, align 16185// CHECK-NEXT: [[TMP2:%.*]] = or i128 [[TMP1]], [[TMP0]]186// CHECK-NEXT: store i128 [[TMP2]], ptr [[AGG_RESULT]], align 8, !tbaa [[__INT128_TBAA6]]187// CHECK-NEXT: ret void188//189__int128 f13() {190 return __atomic_or_fetch(&Ptr, Val, memory_order_seq_cst);191}192 193// CHECK-LABEL: define dso_local void @f14(194// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]]) local_unnamed_addr #[[ATTR0]] {195// CHECK-NEXT: [[ENTRY:.*:]]196// CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 16, !tbaa [[__INT128_TBAA6]]197// CHECK-NEXT: [[TMP1:%.*]] = atomicrmw nand ptr @Ptr, i128 [[TMP0]] seq_cst, align 16198// CHECK-NEXT: [[TMP2:%.*]] = and i128 [[TMP1]], [[TMP0]]199// CHECK-NEXT: [[TMP3:%.*]] = xor i128 [[TMP2]], -1200// CHECK-NEXT: store i128 [[TMP3]], ptr [[AGG_RESULT]], align 8, !tbaa [[__INT128_TBAA6]]201// CHECK-NEXT: ret void202//203__int128 f14() {204 return __atomic_nand_fetch(&Ptr, Val, memory_order_seq_cst);205}206 207// CHECK-LABEL: define dso_local void @f15(208// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]]) local_unnamed_addr #[[ATTR0]] {209// CHECK-NEXT: [[ENTRY:.*:]]210// CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 16, !tbaa [[__INT128_TBAA6]]211// CHECK-NEXT: [[TMP1:%.*]] = atomicrmw add ptr @Ptr, i128 [[TMP0]] seq_cst, align 16212// CHECK-NEXT: store i128 [[TMP1]], ptr [[AGG_RESULT]], align 8, !tbaa [[__INT128_TBAA6]]213// CHECK-NEXT: ret void214//215__int128 f15() {216 return __atomic_fetch_add(&Ptr, Val, memory_order_seq_cst);217}218 219// CHECK-LABEL: define dso_local void @f16(220// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]]) local_unnamed_addr #[[ATTR0]] {221// CHECK-NEXT: [[ENTRY:.*:]]222// CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 16, !tbaa [[__INT128_TBAA6]]223// CHECK-NEXT: [[TMP1:%.*]] = atomicrmw sub ptr @Ptr, i128 [[TMP0]] seq_cst, align 16224// CHECK-NEXT: store i128 [[TMP1]], ptr [[AGG_RESULT]], align 8, !tbaa [[__INT128_TBAA6]]225// CHECK-NEXT: ret void226//227__int128 f16() {228 return __atomic_fetch_sub(&Ptr, Val, memory_order_seq_cst);229}230 231// CHECK-LABEL: define dso_local void @f17(232// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]]) local_unnamed_addr #[[ATTR0]] {233// CHECK-NEXT: [[ENTRY:.*:]]234// CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 16, !tbaa [[__INT128_TBAA6]]235// CHECK-NEXT: [[TMP1:%.*]] = atomicrmw and ptr @Ptr, i128 [[TMP0]] seq_cst, align 16236// CHECK-NEXT: store i128 [[TMP1]], ptr [[AGG_RESULT]], align 8, !tbaa [[__INT128_TBAA6]]237// CHECK-NEXT: ret void238//239__int128 f17() {240 return __atomic_fetch_and(&Ptr, Val, memory_order_seq_cst);241}242 243// CHECK-LABEL: define dso_local void @f18(244// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]]) local_unnamed_addr #[[ATTR0]] {245// CHECK-NEXT: [[ENTRY:.*:]]246// CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 16, !tbaa [[__INT128_TBAA6]]247// CHECK-NEXT: [[TMP1:%.*]] = atomicrmw xor ptr @Ptr, i128 [[TMP0]] seq_cst, align 16248// CHECK-NEXT: store i128 [[TMP1]], ptr [[AGG_RESULT]], align 8, !tbaa [[__INT128_TBAA6]]249// CHECK-NEXT: ret void250//251__int128 f18() {252 return __atomic_fetch_xor(&Ptr, Val, memory_order_seq_cst);253}254 255// CHECK-LABEL: define dso_local void @f19(256// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]]) local_unnamed_addr #[[ATTR0]] {257// CHECK-NEXT: [[ENTRY:.*:]]258// CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 16, !tbaa [[__INT128_TBAA6]]259// CHECK-NEXT: [[TMP1:%.*]] = atomicrmw or ptr @Ptr, i128 [[TMP0]] seq_cst, align 16260// CHECK-NEXT: store i128 [[TMP1]], ptr [[AGG_RESULT]], align 8, !tbaa [[__INT128_TBAA6]]261// CHECK-NEXT: ret void262//263__int128 f19() {264 return __atomic_fetch_or(&Ptr, Val, memory_order_seq_cst);265}266 267// CHECK-LABEL: define dso_local void @f20(268// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]]) local_unnamed_addr #[[ATTR0]] {269// CHECK-NEXT: [[ENTRY:.*:]]270// CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 16, !tbaa [[__INT128_TBAA6]]271// CHECK-NEXT: [[TMP1:%.*]] = atomicrmw nand ptr @Ptr, i128 [[TMP0]] seq_cst, align 16272// CHECK-NEXT: store i128 [[TMP1]], ptr [[AGG_RESULT]], align 8, !tbaa [[__INT128_TBAA6]]273// CHECK-NEXT: ret void274//275__int128 f20() {276 return __atomic_fetch_nand(&Ptr, Val, memory_order_seq_cst);277}278//.279// CHECK: [[META4:![0-9]+]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0}280// CHECK: [[META5]] = !{!"Simple C/C++ TBAA"}281// CHECK: [[__INT128_TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0}282// CHECK: [[META7]] = !{!"__int128", [[META4]], i64 0}283//.284