1; RUN: llc < %s -march=bpfel -mcpu=v3 -verify-machineinstrs -show-mc-encoding | FileCheck %s 2; 3; Source: 4; int test_load_add_32(int *p, int v) { 5; return __sync_fetch_and_add(p, v); 6; } 7; int test_load_add_64(long *p, long v) { 8; return __sync_fetch_and_add(p, v); 9; } 10; int test_load_sub_32(int *p, int v) { 11; return __sync_fetch_and_sub(p, v); 12; } 13; int test_load_sub_64(long *p, long v) { 14; return __sync_fetch_and_sub(p, v); 15; } 16; // from https://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Atomic-Builtins.html 17; // __sync_lock_test_and_set() actually does atomic xchg and returns 18; // old contents. 19; int test_xchg_32(int *p, int v) { 20; return __sync_lock_test_and_set(p, v); 21; } 22; int test_xchg_64(long *p, long v) { 23; return __sync_lock_test_and_set(p, v); 24; } 25; int test_cas_32(int *p, int old, int new) { 26; return __sync_val_compare_and_swap(p, old, new); 27; } 28; long test_cas_64(long *p, long old, long new) { 29; return __sync_val_compare_and_swap(p, old, new); 30; } 31; int test_load_and_32(int *p, int v) { 32; return __sync_fetch_and_and(p, v); 33; } 34; int test_load_and_64(long *p, long v) { 35; return __sync_fetch_and_and(p, v); 36; } 37; int test_load_or_32(int *p, int v) { 38; return __sync_fetch_and_or(p, v); 39; } 40; int test_load_or_64(long *p, long v) { 41; return __sync_fetch_and_or(p, v); 42; } 43; int test_load_xor_32(int *p, int v) { 44; return __sync_fetch_and_xor(p, v); 45; } 46; int test_load_xor_64(long *p, long v) { 47; return __sync_fetch_and_xor(p, v); 48; } 49; int test_atomic_xor_32(int *p, int v) { 50; __sync_fetch_and_xor(p, v); 51; return 0; 52; } 53; int test_atomic_xor_64(long *p, long v) { 54; __sync_fetch_and_xor(p, v); 55; return 0; 56; } 57; int test_atomic_and_64(long *p, long v) { 58; __sync_fetch_and_and(p, v); 59; return 0; 60; } 61; int test_atomic_or_64(long *p, long v) { 62; __sync_fetch_and_or(p, v); 63; return 0; 64; } 65 66; CHECK-LABEL: test_load_add_32 67; CHECK: w0 = w2 68; CHECK: w0 = atomic_fetch_add((u32 *)(r1 + 0), w0) 69; CHECK: encoding: [0xc3,0x01,0x00,0x00,0x01,0x00,0x00,0x00] 70define dso_local i32 @test_load_add_32(i32* nocapture %p, i32 %v) local_unnamed_addr { 71entry: 72 %0 = atomicrmw add i32* %p, i32 %v seq_cst 73 ret i32 %0 74} 75 76; CHECK-LABEL: test_load_add_64 77; CHECK: r0 = r2 78; CHECK: r0 = atomic_fetch_add((u64 *)(r1 + 0), r0) 79; CHECK: encoding: [0xdb,0x01,0x00,0x00,0x01,0x00,0x00,0x00] 80define dso_local i32 @test_load_add_64(i64* nocapture %p, i64 %v) local_unnamed_addr { 81entry: 82 %0 = atomicrmw add i64* %p, i64 %v seq_cst 83 %conv = trunc i64 %0 to i32 84 ret i32 %conv 85} 86 87; CHECK-LABEL: test_load_sub_32 88; CHECK: w0 = w2 89; CHECK: w0 = -w0 90; CHECK: w0 = atomic_fetch_add((u32 *)(r1 + 0), w0) 91; CHECK: encoding: [0xc3,0x01,0x00,0x00,0x01,0x00,0x00,0x00] 92define dso_local i32 @test_load_sub_32(i32* nocapture %p, i32 %v) local_unnamed_addr { 93entry: 94 %0 = atomicrmw sub i32* %p, i32 %v seq_cst 95 ret i32 %0 96} 97 98; CHECK-LABEL: test_load_sub_64 99; CHECK: r0 = r2 100; CHECK: r0 = -r0 101; CHECK: r0 = atomic_fetch_add((u64 *)(r1 + 0), r0) 102; CHECK: encoding: [0xdb,0x01,0x00,0x00,0x01,0x00,0x00,0x00] 103define dso_local i32 @test_load_sub_64(i64* nocapture %p, i64 %v) local_unnamed_addr { 104entry: 105 %0 = atomicrmw sub i64* %p, i64 %v seq_cst 106 %conv = trunc i64 %0 to i32 107 ret i32 %conv 108} 109 110; CHECK-LABEL: test_xchg_32 111; CHECK: w0 = w2 112; CHECK: w0 = xchg32_32(r1 + 0, w0) 113; CHECK: encoding: [0xc3,0x01,0x00,0x00,0xe1,0x00,0x00,0x00] 114define dso_local i32 @test_xchg_32(i32* nocapture %p, i32 %v) local_unnamed_addr { 115entry: 116 %0 = atomicrmw xchg i32* %p, i32 %v seq_cst 117 ret i32 %0 118} 119 120; CHECK-LABEL: test_xchg_64 121; CHECK: r0 = r2 122; CHECK: r0 = xchg_64(r1 + 0, r0) 123; CHECK: encoding: [0xdb,0x01,0x00,0x00,0xe1,0x00,0x00,0x00] 124define dso_local i32 @test_xchg_64(i64* nocapture %p, i64 %v) local_unnamed_addr { 125entry: 126 %0 = atomicrmw xchg i64* %p, i64 %v seq_cst 127 %conv = trunc i64 %0 to i32 128 ret i32 %conv 129} 130 131; CHECK-LABEL: test_cas_32 132; CHECK: w0 = w2 133; CHECK: w0 = cmpxchg32_32(r1 + 0, w0, w3) 134; CHECK: encoding: [0xc3,0x31,0x00,0x00,0xf1,0x00,0x00,0x00] 135define dso_local i32 @test_cas_32(i32* nocapture %p, i32 %old, i32 %new) local_unnamed_addr { 136entry: 137 %0 = cmpxchg i32* %p, i32 %old, i32 %new seq_cst seq_cst 138 %1 = extractvalue { i32, i1 } %0, 0 139 ret i32 %1 140} 141 142; CHECK-LABEL: test_cas_64 143; CHECK: r0 = r2 144; CHECK: r0 = cmpxchg_64(r1 + 0, r0, r3) 145; CHECK: encoding: [0xdb,0x31,0x00,0x00,0xf1,0x00,0x00,0x00] 146define dso_local i64 @test_cas_64(i64* nocapture %p, i64 %old, i64 %new) local_unnamed_addr { 147entry: 148 %0 = cmpxchg i64* %p, i64 %old, i64 %new seq_cst seq_cst 149 %1 = extractvalue { i64, i1 } %0, 0 150 ret i64 %1 151} 152 153; CHECK-LABEL: test_load_and_32 154; CHECK: w0 = w2 155; CHECK: w0 = atomic_fetch_and((u32 *)(r1 + 0), w0) 156; CHECK: encoding: [0xc3,0x01,0x00,0x00,0x51,0x00,0x00,0x00] 157define dso_local i32 @test_load_and_32(i32* nocapture %p, i32 %v) local_unnamed_addr { 158entry: 159 %0 = atomicrmw and i32* %p, i32 %v seq_cst 160 ret i32 %0 161} 162 163; CHECK-LABEL: test_load_and_64 164; CHECK: r0 = r2 165; CHECK: r0 = atomic_fetch_and((u64 *)(r1 + 0), r0) 166; CHECK: encoding: [0xdb,0x01,0x00,0x00,0x51,0x00,0x00,0x00] 167define dso_local i32 @test_load_and_64(i64* nocapture %p, i64 %v) local_unnamed_addr { 168entry: 169 %0 = atomicrmw and i64* %p, i64 %v seq_cst 170 %conv = trunc i64 %0 to i32 171 ret i32 %conv 172} 173 174; CHECK-LABEL: test_load_or_32 175; CHECK: w0 = w2 176; CHECK: w0 = atomic_fetch_or((u32 *)(r1 + 0), w0) 177; CHECK: encoding: [0xc3,0x01,0x00,0x00,0x41,0x00,0x00,0x00] 178define dso_local i32 @test_load_or_32(i32* nocapture %p, i32 %v) local_unnamed_addr { 179entry: 180 %0 = atomicrmw or i32* %p, i32 %v seq_cst 181 ret i32 %0 182} 183 184; CHECK-LABEL: test_load_or_64 185; CHECK: r0 = r2 186; CHECK: r0 = atomic_fetch_or((u64 *)(r1 + 0), r0) 187; CHECK: encoding: [0xdb,0x01,0x00,0x00,0x41,0x00,0x00,0x00] 188define dso_local i32 @test_load_or_64(i64* nocapture %p, i64 %v) local_unnamed_addr { 189entry: 190 %0 = atomicrmw or i64* %p, i64 %v seq_cst 191 %conv = trunc i64 %0 to i32 192 ret i32 %conv 193} 194 195; CHECK-LABEL: test_load_xor_32 196; CHECK: w0 = w2 197; CHECK: w0 = atomic_fetch_xor((u32 *)(r1 + 0), w0) 198; CHECK: encoding: [0xc3,0x01,0x00,0x00,0xa1,0x00,0x00,0x00] 199define dso_local i32 @test_load_xor_32(i32* nocapture %p, i32 %v) local_unnamed_addr { 200entry: 201 %0 = atomicrmw xor i32* %p, i32 %v seq_cst 202 ret i32 %0 203} 204 205; CHECK-LABEL: test_load_xor_64 206; CHECK: r0 = r2 207; CHECK: r0 = atomic_fetch_xor((u64 *)(r1 + 0), r0) 208; CHECK: encoding: [0xdb,0x01,0x00,0x00,0xa1,0x00,0x00,0x00] 209define dso_local i32 @test_load_xor_64(i64* nocapture %p, i64 %v) local_unnamed_addr { 210entry: 211 %0 = atomicrmw xor i64* %p, i64 %v seq_cst 212 %conv = trunc i64 %0 to i32 213 ret i32 %conv 214} 215 216; CHECK-LABEL: test_atomic_xor_32 217; CHECK: lock *(u32 *)(r1 + 0) ^= w2 218; CHECK: encoding: [0xc3,0x21,0x00,0x00,0xa0,0x00,0x00,0x00] 219; CHECK: w0 = 0 220define dso_local i32 @test_atomic_xor_32(i32* nocapture %p, i32 %v) local_unnamed_addr { 221entry: 222 %0 = atomicrmw xor i32* %p, i32 %v seq_cst 223 ret i32 0 224} 225 226; CHECK-LABEL: test_atomic_xor_64 227; CHECK: lock *(u64 *)(r1 + 0) ^= r2 228; CHECK: encoding: [0xdb,0x21,0x00,0x00,0xa0,0x00,0x00,0x00] 229; CHECK: w0 = 0 230define dso_local i32 @test_atomic_xor_64(i64* nocapture %p, i64 %v) local_unnamed_addr { 231entry: 232 %0 = atomicrmw xor i64* %p, i64 %v seq_cst 233 ret i32 0 234} 235 236; CHECK-LABEL: test_atomic_and_64 237; CHECK: lock *(u64 *)(r1 + 0) &= r2 238; CHECK: encoding: [0xdb,0x21,0x00,0x00,0x50,0x00,0x00,0x00] 239; CHECK: w0 = 0 240define dso_local i32 @test_atomic_and_64(i64* nocapture %p, i64 %v) local_unnamed_addr { 241entry: 242 %0 = atomicrmw and i64* %p, i64 %v seq_cst 243 ret i32 0 244} 245 246; CHECK-LABEL: test_atomic_or_64 247; CHECK: lock *(u64 *)(r1 + 0) |= r2 248; CHECK: encoding: [0xdb,0x21,0x00,0x00,0x40,0x00,0x00,0x00] 249; CHECK: w0 = 0 250define dso_local i32 @test_atomic_or_64(i64* nocapture %p, i64 %v) local_unnamed_addr { 251entry: 252 %0 = atomicrmw or i64* %p, i64 %v seq_cst 253 ret i32 0 254} 255