1f3fb9739STomas Matheson#!/usr/bin/env python3 2f3fb9739STomas Mathesonimport textwrap 3f3fb9739STomas Mathesonimport enum 4f3fb9739STomas Mathesonimport os 5*b71edfaaSTobias Hieta 6f3fb9739STomas Matheson""" 7f3fb9739STomas MathesonGenerate the tests in llvm/test/CodeGen/AArch64/Atomics. Run from top level llvm-project. 8f3fb9739STomas Matheson""" 9f3fb9739STomas Matheson 10f3fb9739STomas MathesonTRIPLES = [ 11*b71edfaaSTobias Hieta "aarch64", 12*b71edfaaSTobias Hieta "aarch64_be", 13f3fb9739STomas Matheson] 14f3fb9739STomas Matheson 15f3fb9739STomas Matheson 16f3fb9739STomas Matheson# Type name size 17f3fb9739STomas Mathesonclass Type(enum.Enum): 18f3fb9739STomas Matheson # Value is the size in bytes 19f3fb9739STomas Matheson i8 = 1 20f3fb9739STomas Matheson i16 = 2 21f3fb9739STomas Matheson i32 = 4 22f3fb9739STomas Matheson i64 = 8 23f3fb9739STomas Matheson i128 = 16 24f3fb9739STomas Matheson 25f3fb9739STomas Matheson def align(self, aligned: bool) -> int: 26f3fb9739STomas Matheson return self.value if aligned else 1 27f3fb9739STomas Matheson 28f3fb9739STomas Matheson def __str__(self) -> str: 29f3fb9739STomas Matheson return self.name 30f3fb9739STomas Matheson 31f3fb9739STomas Matheson 32f3fb9739STomas Matheson# Is this an aligned or unaligned access? 33f3fb9739STomas Mathesonclass Aligned(enum.Enum): 34f3fb9739STomas Matheson aligned = True 35f3fb9739STomas Matheson unaligned = False 36f3fb9739STomas Matheson 37f3fb9739STomas Matheson def __str__(self) -> str: 38f3fb9739STomas Matheson return self.name 39f3fb9739STomas Matheson 40f3fb9739STomas Matheson def __bool__(self) -> bool: 41f3fb9739STomas Matheson return self.value 42f3fb9739STomas Matheson 43f3fb9739STomas Matheson 44f3fb9739STomas Mathesonclass AtomicOrder(enum.Enum): 45f3fb9739STomas Matheson notatomic = 0 46f3fb9739STomas Matheson unordered = 1 47f3fb9739STomas Matheson monotonic = 2 48f3fb9739STomas Matheson acquire = 3 49f3fb9739STomas Matheson release = 4 50f3fb9739STomas Matheson acq_rel = 5 51f3fb9739STomas Matheson seq_cst = 6 52f3fb9739STomas Matheson 53f3fb9739STomas Matheson def __str__(self) -> str: 54f3fb9739STomas Matheson return self.name 55f3fb9739STomas Matheson 56f3fb9739STomas Matheson 57f3fb9739STomas MathesonATOMICRMW_ORDERS = [ 58f3fb9739STomas Matheson AtomicOrder.monotonic, 59f3fb9739STomas Matheson AtomicOrder.acquire, 60f3fb9739STomas Matheson AtomicOrder.release, 61f3fb9739STomas Matheson AtomicOrder.acq_rel, 62f3fb9739STomas Matheson AtomicOrder.seq_cst, 63f3fb9739STomas Matheson] 64f3fb9739STomas Matheson 65f3fb9739STomas MathesonATOMIC_LOAD_ORDERS = [ 66f3fb9739STomas Matheson AtomicOrder.unordered, 67f3fb9739STomas Matheson AtomicOrder.monotonic, 68f3fb9739STomas Matheson AtomicOrder.acquire, 69f3fb9739STomas Matheson AtomicOrder.seq_cst, 70f3fb9739STomas Matheson] 71f3fb9739STomas Matheson 72f3fb9739STomas MathesonATOMIC_STORE_ORDERS = [ 73f3fb9739STomas Matheson AtomicOrder.unordered, 74f3fb9739STomas Matheson AtomicOrder.monotonic, 75f3fb9739STomas Matheson AtomicOrder.release, 76f3fb9739STomas Matheson AtomicOrder.seq_cst, 77f3fb9739STomas Matheson] 78f3fb9739STomas Matheson 79f3fb9739STomas MathesonATOMIC_FENCE_ORDERS = [ 80f3fb9739STomas Matheson AtomicOrder.acquire, 81f3fb9739STomas Matheson AtomicOrder.release, 82f3fb9739STomas Matheson AtomicOrder.acq_rel, 83f3fb9739STomas Matheson AtomicOrder.seq_cst, 84f3fb9739STomas Matheson] 85f3fb9739STomas Matheson 86f3fb9739STomas MathesonCMPXCHG_SUCCESS_ORDERS = [ 87f3fb9739STomas Matheson AtomicOrder.monotonic, 88f3fb9739STomas Matheson AtomicOrder.acquire, 89f3fb9739STomas Matheson AtomicOrder.release, 90f3fb9739STomas Matheson AtomicOrder.acq_rel, 91f3fb9739STomas Matheson AtomicOrder.seq_cst, 92f3fb9739STomas Matheson] 93f3fb9739STomas Matheson 94f3fb9739STomas MathesonCMPXCHG_FAILURE_ORDERS = [ 95f3fb9739STomas Matheson AtomicOrder.monotonic, 96f3fb9739STomas Matheson AtomicOrder.acquire, 97f3fb9739STomas Matheson AtomicOrder.seq_cst, 98f3fb9739STomas Matheson] 99f3fb9739STomas Matheson 100f3fb9739STomas MathesonFENCE_ORDERS = [ 101f3fb9739STomas Matheson AtomicOrder.acquire, 102f3fb9739STomas Matheson AtomicOrder.release, 103f3fb9739STomas Matheson AtomicOrder.acq_rel, 104f3fb9739STomas Matheson AtomicOrder.seq_cst, 105f3fb9739STomas Matheson] 106f3fb9739STomas Matheson 107f3fb9739STomas Matheson 108f3fb9739STomas Mathesonclass Feature(enum.Flag): 1097c84f94eSTomas Matheson # Feature names in filenames are determined by the spelling here: 110f3fb9739STomas Matheson v8a = enum.auto() 111f3fb9739STomas Matheson v8_1a = enum.auto() # -mattr=+v8.1a, mandatory FEAT_LOR, FEAT_LSE 112f3fb9739STomas Matheson rcpc = enum.auto() # FEAT_LRCPC 113f3fb9739STomas Matheson lse2 = enum.auto() # FEAT_LSE2 114f3fb9739STomas Matheson outline_atomics = enum.auto() # -moutline-atomics 1157c84f94eSTomas Matheson rcpc3 = enum.auto() # FEAT_LSE2 + FEAT_LRCPC3 1165a9cb377STomas Matheson lse2_lse128 = enum.auto() # FEAT_LSE2 + FEAT_LSE128 117f3fb9739STomas Matheson 118f3fb9739STomas Matheson @property 119f3fb9739STomas Matheson def mattr(self): 120f3fb9739STomas Matheson if self == Feature.outline_atomics: 121*b71edfaaSTobias Hieta return "+outline-atomics" 122f3fb9739STomas Matheson if self == Feature.v8_1a: 123*b71edfaaSTobias Hieta return "+v8.1a" 1247c84f94eSTomas Matheson if self == Feature.rcpc3: 125*b71edfaaSTobias Hieta return "+lse2,+rcpc3" 1265a9cb377STomas Matheson if self == Feature.lse2_lse128: 127*b71edfaaSTobias Hieta return "+lse2,+lse128" 128*b71edfaaSTobias Hieta return "+" + self.name 129f3fb9739STomas Matheson 130f3fb9739STomas Matheson 131f3fb9739STomas MathesonATOMICRMW_OPS = [ 132*b71edfaaSTobias Hieta "xchg", 133*b71edfaaSTobias Hieta "add", 134*b71edfaaSTobias Hieta "sub", 135*b71edfaaSTobias Hieta "and", 136*b71edfaaSTobias Hieta "nand", 137*b71edfaaSTobias Hieta "or", 138*b71edfaaSTobias Hieta "xor", 139*b71edfaaSTobias Hieta "max", 140*b71edfaaSTobias Hieta "min", 141*b71edfaaSTobias Hieta "umax", 142*b71edfaaSTobias Hieta "umin", 143f3fb9739STomas Matheson] 144f3fb9739STomas Matheson 145f3fb9739STomas Matheson 146f3fb9739STomas Mathesondef all_atomicrmw(f): 147f3fb9739STomas Matheson for op in ATOMICRMW_OPS: 148f3fb9739STomas Matheson for aligned in Aligned: 149f3fb9739STomas Matheson for ty in Type: 150f3fb9739STomas Matheson for ordering in ATOMICRMW_ORDERS: 151*b71edfaaSTobias Hieta name = f"atomicrmw_{op}_{ty}_{aligned}_{ordering}" 152*b71edfaaSTobias Hieta instr = "atomicrmw" 153f3fb9739STomas Matheson f.write( 154*b71edfaaSTobias Hieta textwrap.dedent( 155*b71edfaaSTobias Hieta f""" 156f3fb9739STomas Matheson define dso_local {ty} @{name}(ptr %ptr, {ty} %value) {{ 157f3fb9739STomas Matheson %r = {instr} {op} ptr %ptr, {ty} %value {ordering}, align {ty.align(aligned)} 158f3fb9739STomas Matheson ret {ty} %r 159f3fb9739STomas Matheson }} 160*b71edfaaSTobias Hieta """ 161*b71edfaaSTobias Hieta ) 162*b71edfaaSTobias Hieta ) 163f3fb9739STomas Matheson 164f3fb9739STomas Matheson 165f3fb9739STomas Mathesondef all_load(f): 166f3fb9739STomas Matheson for aligned in Aligned: 167f3fb9739STomas Matheson for ty in Type: 168f3fb9739STomas Matheson for ordering in ATOMIC_LOAD_ORDERS: 169f3fb9739STomas Matheson for const in [False, True]: 170*b71edfaaSTobias Hieta name = f"load_atomic_{ty}_{aligned}_{ordering}" 171*b71edfaaSTobias Hieta instr = "load atomic" 172f3fb9739STomas Matheson if const: 173*b71edfaaSTobias Hieta name += "_const" 174*b71edfaaSTobias Hieta arg = "ptr readonly %ptr" if const else "ptr %ptr" 175f3fb9739STomas Matheson f.write( 176*b71edfaaSTobias Hieta textwrap.dedent( 177*b71edfaaSTobias Hieta f""" 178f3fb9739STomas Matheson define dso_local {ty} @{name}({arg}) {{ 179f3fb9739STomas Matheson %r = {instr} {ty}, ptr %ptr {ordering}, align {ty.align(aligned)} 180f3fb9739STomas Matheson ret {ty} %r 181f3fb9739STomas Matheson }} 182*b71edfaaSTobias Hieta """ 183*b71edfaaSTobias Hieta ) 184*b71edfaaSTobias Hieta ) 185f3fb9739STomas Matheson 186f3fb9739STomas Matheson 187f3fb9739STomas Mathesondef all_store(f): 188f3fb9739STomas Matheson for aligned in Aligned: 189f3fb9739STomas Matheson for ty in Type: 190f3fb9739STomas Matheson for ordering in ATOMIC_STORE_ORDERS: # FIXME stores 191*b71edfaaSTobias Hieta name = f"store_atomic_{ty}_{aligned}_{ordering}" 192*b71edfaaSTobias Hieta instr = "store atomic" 193f3fb9739STomas Matheson f.write( 194*b71edfaaSTobias Hieta textwrap.dedent( 195*b71edfaaSTobias Hieta f""" 196f3fb9739STomas Matheson define dso_local void @{name}({ty} %value, ptr %ptr) {{ 197f3fb9739STomas Matheson {instr} {ty} %value, ptr %ptr {ordering}, align {ty.align(aligned)} 198f3fb9739STomas Matheson ret void 199f3fb9739STomas Matheson }} 200*b71edfaaSTobias Hieta """ 201*b71edfaaSTobias Hieta ) 202*b71edfaaSTobias Hieta ) 203f3fb9739STomas Matheson 204f3fb9739STomas Matheson 205f3fb9739STomas Mathesondef all_cmpxchg(f): 206f3fb9739STomas Matheson for aligned in Aligned: 207f3fb9739STomas Matheson for ty in Type: 208f3fb9739STomas Matheson for success_ordering in CMPXCHG_SUCCESS_ORDERS: 209f3fb9739STomas Matheson for failure_ordering in CMPXCHG_FAILURE_ORDERS: 210f3fb9739STomas Matheson for weak in [False, True]: 211*b71edfaaSTobias Hieta name = f"cmpxchg_{ty}_{aligned}_{success_ordering}_{failure_ordering}" 212*b71edfaaSTobias Hieta instr = "cmpxchg" 213f3fb9739STomas Matheson if weak: 214*b71edfaaSTobias Hieta name += "_weak" 215*b71edfaaSTobias Hieta instr += " weak" 216f3fb9739STomas Matheson f.write( 217*b71edfaaSTobias Hieta textwrap.dedent( 218*b71edfaaSTobias Hieta f""" 219f3fb9739STomas Matheson define dso_local {ty} @{name}({ty} %expected, {ty} %new, ptr %ptr) {{ 220f3fb9739STomas Matheson %pair = {instr} ptr %ptr, {ty} %expected, {ty} %new {success_ordering} {failure_ordering}, align {ty.align(aligned)} 221f3fb9739STomas Matheson %r = extractvalue {{ {ty}, i1 }} %pair, 0 222f3fb9739STomas Matheson ret {ty} %r 223f3fb9739STomas Matheson }} 224*b71edfaaSTobias Hieta """ 225*b71edfaaSTobias Hieta ) 226*b71edfaaSTobias Hieta ) 227f3fb9739STomas Matheson 228f3fb9739STomas Matheson 229f3fb9739STomas Mathesondef all_fence(f): 230f3fb9739STomas Matheson for ordering in FENCE_ORDERS: 231*b71edfaaSTobias Hieta name = f"fence_{ordering}" 232f3fb9739STomas Matheson f.write( 233*b71edfaaSTobias Hieta textwrap.dedent( 234*b71edfaaSTobias Hieta f""" 235f3fb9739STomas Matheson define dso_local void @{name}() {{ 236f3fb9739STomas Matheson fence {ordering} 237f3fb9739STomas Matheson ret void 238f3fb9739STomas Matheson }} 239*b71edfaaSTobias Hieta """ 240*b71edfaaSTobias Hieta ) 241*b71edfaaSTobias Hieta ) 242f3fb9739STomas Matheson 243f3fb9739STomas Matheson 244f3fb9739STomas Mathesondef header(f, triple, features, filter_args: str): 245*b71edfaaSTobias Hieta f.write( 246*b71edfaaSTobias Hieta "; NOTE: Assertions have been autogenerated by " 247*b71edfaaSTobias Hieta "utils/update_llc_test_checks.py UTC_ARGS: " 248*b71edfaaSTobias Hieta ) 249f3fb9739STomas Matheson f.write(filter_args) 250*b71edfaaSTobias Hieta f.write("\n") 251*b71edfaaSTobias Hieta f.write(f"; The base test file was generated by {__file__}\n") 252f3fb9739STomas Matheson for feat in features: 253*b71edfaaSTobias Hieta for OptFlag in ["-O0", "-O1"]: 254*b71edfaaSTobias Hieta f.write( 255*b71edfaaSTobias Hieta " ".join( 256*b71edfaaSTobias Hieta [ 257*b71edfaaSTobias Hieta ";", 258*b71edfaaSTobias Hieta "RUN:", 259*b71edfaaSTobias Hieta "llc", 260*b71edfaaSTobias Hieta "%s", 261*b71edfaaSTobias Hieta "-o", 262*b71edfaaSTobias Hieta "-", 263*b71edfaaSTobias Hieta "-verify-machineinstrs", 264*b71edfaaSTobias Hieta f"-mtriple={triple}", 265*b71edfaaSTobias Hieta f"-mattr={feat.mattr}", 266*b71edfaaSTobias Hieta OptFlag, 267*b71edfaaSTobias Hieta "|", 268*b71edfaaSTobias Hieta "FileCheck", 269*b71edfaaSTobias Hieta "%s", 270*b71edfaaSTobias Hieta f"--check-prefixes=CHECK,{OptFlag}\n", 271*b71edfaaSTobias Hieta ] 272*b71edfaaSTobias Hieta ) 273*b71edfaaSTobias Hieta ) 274f3fb9739STomas Matheson 275f3fb9739STomas Matheson 276f3fb9739STomas Mathesondef write_lit_tests(): 277*b71edfaaSTobias Hieta os.chdir("llvm/test/CodeGen/AArch64/Atomics/") 278f3fb9739STomas Matheson for triple in TRIPLES: 279f3fb9739STomas Matheson # Feature has no effect on fence, so keep it to one file. 280*b71edfaaSTobias Hieta with open(f"{triple}-fence.ll", "w") as f: 281f3fb9739STomas Matheson filter_args = r'--filter "^\s*(dmb)"' 282f3fb9739STomas Matheson header(f, triple, Feature, filter_args) 283f3fb9739STomas Matheson all_fence(f) 284f3fb9739STomas Matheson 285f3fb9739STomas Matheson for feat in Feature: 286*b71edfaaSTobias Hieta with open(f"{triple}-atomicrmw-{feat.name}.ll", "w") as f: 287f3fb9739STomas Matheson filter_args = r'--filter-out "\b(sp)\b" --filter "^\s*(ld[^r]|st[^r]|swp|cas|bl|add|and|eor|orn|orr|sub|mvn|sxt|cmp|ccmp|csel|dmb)"' 288f3fb9739STomas Matheson header(f, triple, [feat], filter_args) 289f3fb9739STomas Matheson all_atomicrmw(f) 290f3fb9739STomas Matheson 291*b71edfaaSTobias Hieta with open(f"{triple}-cmpxchg-{feat.name}.ll", "w") as f: 292f3fb9739STomas Matheson filter_args = r'--filter-out "\b(sp)\b" --filter "^\s*(ld[^r]|st[^r]|swp|cas|bl|add|and|eor|orn|orr|sub|mvn|sxt|cmp|ccmp|csel|dmb)"' 293f3fb9739STomas Matheson header(f, triple, [feat], filter_args) 294f3fb9739STomas Matheson all_cmpxchg(f) 295f3fb9739STomas Matheson 296*b71edfaaSTobias Hieta with open(f"{triple}-atomic-load-{feat.name}.ll", "w") as f: 297f3fb9739STomas Matheson filter_args = r'--filter-out "\b(sp)\b" --filter "^\s*(ld|st[^r]|swp|cas|bl|add|and|eor|orn|orr|sub|mvn|sxt|cmp|ccmp|csel|dmb)"' 298f3fb9739STomas Matheson header(f, triple, [feat], filter_args) 299f3fb9739STomas Matheson all_load(f) 300f3fb9739STomas Matheson 301*b71edfaaSTobias Hieta with open(f"{triple}-atomic-store-{feat.name}.ll", "w") as f: 302f3fb9739STomas Matheson filter_args = r'--filter-out "\b(sp)\b" --filter "^\s*(ld[^r]|st|swp|cas|bl|add|and|eor|orn|orr|sub|mvn|sxt|cmp|ccmp|csel|dmb)"' 303f3fb9739STomas Matheson header(f, triple, [feat], filter_args) 304f3fb9739STomas Matheson all_store(f) 305f3fb9739STomas Matheson 306*b71edfaaSTobias Hieta 307*b71edfaaSTobias Hietaif __name__ == "__main__": 308f3fb9739STomas Matheson write_lit_tests() 309f3fb9739STomas Matheson 310*b71edfaaSTobias Hieta print( 311*b71edfaaSTobias Hieta textwrap.dedent( 312*b71edfaaSTobias Hieta """ 313f3fb9739STomas Matheson Testcases written. To update checks run: 314f3fb9739STomas Matheson $ ./llvm/utils/update_llc_test_checks.py -u llvm/test/CodeGen/AArch64/Atomics/*.ll 315f3fb9739STomas Matheson 316f3fb9739STomas Matheson Or in parallel: 317f3fb9739STomas Matheson $ parallel ./llvm/utils/update_llc_test_checks.py -u ::: llvm/test/CodeGen/AArch64/Atomics/*.ll 318*b71edfaaSTobias Hieta """ 319*b71edfaaSTobias Hieta ) 320*b71edfaaSTobias Hieta ) 321