1; RUN: llc -march=mipsel --disable-machine-licm -mcpu=mips32 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS32-ANY -check-prefix=NO-SEB-SEH -check-prefix=CHECK-EL -check-prefix=NOT-MICROMIPS 2; RUN: llc -march=mipsel --disable-machine-licm -mcpu=mips32r2 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS32-ANY -check-prefix=HAS-SEB-SEH -check-prefix=CHECK-EL -check-prefix=NOT-MICROMIPS 3; RUN: llc -march=mipsel --disable-machine-licm -mcpu=mips32r6 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS32-ANY -check-prefix=HAS-SEB-SEH -check-prefix=CHECK-EL -check-prefix=MIPSR6 4; RUN: llc -march=mips64el --disable-machine-licm -mcpu=mips4 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS64-ANY -check-prefix=NO-SEB-SEH -check-prefix=CHECK-EL -check-prefix=NOT-MICROMIPS 5; RUN: llc -march=mips64el --disable-machine-licm -mcpu=mips64 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS64-ANY -check-prefix=NO-SEB-SEH -check-prefix=CHECK-EL -check-prefix=NOT-MICROMIPS 6; RUN: llc -march=mips64el --disable-machine-licm -mcpu=mips64r2 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS64-ANY -check-prefix=HAS-SEB-SEH -check-prefix=CHECK-EL -check-prefix=NOT-MICROMIPS 7; RUN: llc -march=mips64el --disable-machine-licm -mcpu=mips64r6 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS64-ANY -check-prefix=HAS-SEB-SEH -check-prefix=CHECK-EL -check-prefix=MIPSR6 8; RUN: llc -march=mips64 -O0 -mcpu=mips64r6 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL-LABEL -check-prefix=MIPS64-ANY -check-prefix=O0 9;; RUN: llc -march=mipsel --disable-machine-licm -mcpu=mips32r2 -mattr=micromips -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS32-ANY -check-prefix=HAS-SEB-SEH -check-prefix=CHECK-EL -check-prefix=MICROMIPS 10 11; Keep one big-endian check so that we don't reduce testing, but don't add more 12; since endianness doesn't affect the body of the atomic operations. 13; RUN: llc -march=mips --disable-machine-licm -mcpu=mips32 -relocation-model=pic < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS32-ANY -check-prefix=NO-SEB-SEH -check-prefix=CHECK-EB -check-prefix=NOT-MICROMIPS 14 15@x = common global i32 0, align 4 16 17define i32 @AtomicLoadAdd32(i32 signext %incr) nounwind { 18entry: 19 %0 = atomicrmw add i32* @x, i32 %incr monotonic 20 ret i32 %0 21 22; ALL-LABEL: AtomicLoadAdd32: 23 24; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(x) 25; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(x)( 26 27; O0: $[[BB0:[A-Z_0-9]+]]: 28; O0: ld $[[R1:[0-9]+]] 29; O0-NEXT: ll $[[R2:[0-9]+]], 0($[[R1]]) 30 31; ALL: $[[BB0:[A-Z_0-9]+]]: 32; ALL: ll $[[R3:[0-9]+]], 0($[[R0]]) 33; ALL: addu $[[R4:[0-9]+]], $[[R3]], $4 34; ALL: sc $[[R4]], 0($[[R0]]) 35; NOT-MICROMIPS: beqz $[[R4]], $[[BB0]] 36; MICROMIPS: beqzc $[[R4]], $[[BB0]] 37; MIPSR6: beqzc $[[R4]], $[[BB0]] 38} 39 40define i32 @AtomicLoadNand32(i32 signext %incr) nounwind { 41entry: 42 %0 = atomicrmw nand i32* @x, i32 %incr monotonic 43 ret i32 %0 44 45; ALL-LABEL: AtomicLoadNand32: 46 47; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(x) 48; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(x)( 49 50 51 52; ALL: $[[BB0:[A-Z_0-9]+]]: 53; ALL: ll $[[R1:[0-9]+]], 0($[[R0]]) 54; ALL: and $[[R3:[0-9]+]], $[[R1]], $4 55; ALL: nor $[[R2:[0-9]+]], $zero, $[[R3]] 56; ALL: sc $[[R2]], 0($[[R0]]) 57; NOT-MICROMIPS: beqz $[[R2]], $[[BB0]] 58; MICROMIPS: beqzc $[[R2]], $[[BB0]] 59; MIPSR6: beqzc $[[R2]], $[[BB0]] 60} 61 62define i32 @AtomicSwap32(i32 signext %newval) nounwind { 63entry: 64 %newval.addr = alloca i32, align 4 65 store i32 %newval, i32* %newval.addr, align 4 66 %tmp = load i32, i32* %newval.addr, align 4 67 %0 = atomicrmw xchg i32* @x, i32 %tmp monotonic 68 ret i32 %0 69 70; ALL-LABEL: AtomicSwap32: 71 72; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(x) 73; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(x) 74 75; ALL: $[[BB0:[A-Z_0-9]+]]: 76; ALL: ll ${{[0-9]+}}, 0($[[R0]]) 77; ALL: sc $[[R2:[0-9]+]], 0($[[R0]]) 78; NOT-MICROMIPS: beqz $[[R2]], $[[BB0]] 79; MICROMIPS: beqzc $[[R2]], $[[BB0]] 80; MIPSR6: beqzc $[[R2]], $[[BB0]] 81} 82 83define i32 @AtomicCmpSwap32(i32 signext %oldval, i32 signext %newval) nounwind { 84entry: 85 %newval.addr = alloca i32, align 4 86 store i32 %newval, i32* %newval.addr, align 4 87 %tmp = load i32, i32* %newval.addr, align 4 88 %0 = cmpxchg i32* @x, i32 %oldval, i32 %tmp monotonic monotonic 89 %1 = extractvalue { i32, i1 } %0, 0 90 ret i32 %1 91 92; ALL-LABEL: AtomicCmpSwap32: 93 94; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(x) 95; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(x)( 96 97; ALL: $[[BB0:[A-Z_0-9]+]]: 98; ALL: ll $2, 0($[[R0]]) 99; NOT-MICROMIPS: bne $2, $4, $[[BB1:[A-Z_0-9]+]] 100; MICROMIPS: bne $2, $4, $[[BB1:[A-Z_0-9]+]] 101; MIPSR6: bnec $2, $4, $[[BB1:[A-Z_0-9]+]] 102; ALL: sc $[[R2:[0-9]+]], 0($[[R0]]) 103; NOT-MICROMIPS: beqz $[[R2]], $[[BB0]] 104; MICROMIPS: beqzc $[[R2]], $[[BB0]] 105; MIPSR6: beqzc $[[R2]], $[[BB0]] 106; ALL: $[[BB1]]: 107} 108 109 110 111@y = common global i8 0, align 1 112 113define signext i8 @AtomicLoadAdd8(i8 signext %incr) nounwind { 114entry: 115 %0 = atomicrmw add i8* @y, i8 %incr monotonic 116 ret i8 %0 117 118; ALL-LABEL: AtomicLoadAdd8: 119 120; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(y) 121; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(y)( 122 123; ALL: addiu $[[R1:[0-9]+]], $zero, -4 124; ALL: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] 125; ALL: andi $[[R3:[0-9]+]], $[[R0]], 3 126; CHECK-EB: xori $[[R4:[0-9]+]], $[[R3]], 3 127; CHECK-EB: sll $[[R5:[0-9]+]], $[[R4]], 3 128; CHECK-EL: sll $[[R5:[0-9]+]], $[[R3]], 3 129; ALL: ori $[[R6:[0-9]+]], $zero, 255 130; ALL: sllv $[[R7:[0-9]+]], $[[R6]], $[[R5]] 131; ALL: nor $[[R8:[0-9]+]], $zero, $[[R7]] 132; ALL: sllv $[[R9:[0-9]+]], $4, $[[R5]] 133 134; O0: $[[BB0:[A-Z_0-9]+]]: 135; O0: ld $[[R10:[0-9]+]] 136; O0-NEXT: ll $[[R11:[0-9]+]], 0($[[R10]]) 137 138; ALL: $[[BB0:[A-Z_0-9]+]]: 139; ALL: ll $[[R12:[0-9]+]], 0($[[R2]]) 140; ALL: addu $[[R13:[0-9]+]], $[[R12]], $[[R9]] 141; ALL: and $[[R14:[0-9]+]], $[[R13]], $[[R7]] 142; ALL: and $[[R15:[0-9]+]], $[[R12]], $[[R8]] 143; ALL: or $[[R16:[0-9]+]], $[[R15]], $[[R14]] 144; ALL: sc $[[R16]], 0($[[R2]]) 145; NOT-MICROMIPS: beqz $[[R16]], $[[BB0]] 146; MICROMIPS: beqzc $[[R16]], $[[BB0]] 147; MIPSR6: beqzc $[[R16]], $[[BB0]] 148 149; ALL: and $[[R17:[0-9]+]], $[[R12]], $[[R7]] 150; ALL: srlv $[[R18:[0-9]+]], $[[R17]], $[[R5]] 151 152; NO-SEB-SEH: sll $[[R19:[0-9]+]], $[[R18]], 24 153; NO-SEB-SEH: sra $2, $[[R19]], 24 154 155; HAS-SEB-SEH: seb $2, $[[R18]] 156} 157 158define signext i8 @AtomicLoadSub8(i8 signext %incr) nounwind { 159entry: 160 %0 = atomicrmw sub i8* @y, i8 %incr monotonic 161 ret i8 %0 162 163; ALL-LABEL: AtomicLoadSub8: 164 165; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(y) 166; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(y)( 167 168; ALL: addiu $[[R1:[0-9]+]], $zero, -4 169; ALL: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] 170; ALL: andi $[[R3:[0-9]+]], $[[R0]], 3 171; CHECK-EL: sll $[[R5:[0-9]+]], $[[R3]], 3 172; CHECK-EB: xori $[[R4:[0-9]+]], $[[R3]], 3 173; CHECK-EB: sll $[[R5:[0-9]+]], $[[R4]], 3 174; ALL: ori $[[R6:[0-9]+]], $zero, 255 175; ALL: sllv $[[R7:[0-9]+]], $[[R6]], $[[R5]] 176; ALL: nor $[[R8:[0-9]+]], $zero, $[[R7]] 177; ALL: sllv $[[R9:[0-9]+]], $4, $[[R5]] 178 179; O0: $[[BB0:[A-Z_0-9]+]]: 180; O0: ld $[[R10:[0-9]+]] 181; O0-NEXT: ll $[[R11:[0-9]+]], 0($[[R10]]) 182 183; ALL: $[[BB0:[A-Z_0-9]+]]: 184; ALL: ll $[[R12:[0-9]+]], 0($[[R2]]) 185; ALL: subu $[[R13:[0-9]+]], $[[R12]], $[[R9]] 186; ALL: and $[[R14:[0-9]+]], $[[R13]], $[[R7]] 187; ALL: and $[[R15:[0-9]+]], $[[R12]], $[[R8]] 188; ALL: or $[[R16:[0-9]+]], $[[R15]], $[[R14]] 189; ALL: sc $[[R16]], 0($[[R2]]) 190; NOT-MICROMIPS: beqz $[[R16]], $[[BB0]] 191; MICROMIPS: beqzc $[[R16]], $[[BB0]] 192; MIPSR6: beqzc $[[R16]], $[[BB0]] 193 194; ALL: and $[[R17:[0-9]+]], $[[R12]], $[[R7]] 195; ALL: srlv $[[R18:[0-9]+]], $[[R17]], $[[R5]] 196 197; NO-SEB-SEH: sll $[[R19:[0-9]+]], $[[R18]], 24 198; NO-SEB-SEH: sra $2, $[[R19]], 24 199 200; HAS-SEB-SEH:seb $2, $[[R18]] 201} 202 203define signext i8 @AtomicLoadNand8(i8 signext %incr) nounwind { 204entry: 205 %0 = atomicrmw nand i8* @y, i8 %incr monotonic 206 ret i8 %0 207 208; ALL-LABEL: AtomicLoadNand8: 209 210; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(y) 211; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(y)( 212 213; ALL: addiu $[[R1:[0-9]+]], $zero, -4 214; ALL: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] 215; ALL: andi $[[R3:[0-9]+]], $[[R0]], 3 216; CHECK-EL: sll $[[R5:[0-9]+]], $[[R3]], 3 217; CHECK-EB: xori $[[R4:[0-9]+]], $[[R3]], 3 218; CHECK-EB: sll $[[R5:[0-9]+]], $[[R4]], 3 219; ALL: ori $[[R6:[0-9]+]], $zero, 255 220; ALL: sllv $[[R7:[0-9]+]], $[[R6]], $[[R5]] 221; ALL: nor $[[R8:[0-9]+]], $zero, $[[R7]] 222; ALL: sllv $[[R9:[0-9]+]], $4, $[[R5]] 223 224; O0: $[[BB0:[A-Z_0-9]+]]: 225; O0: ld $[[R10:[0-9]+]] 226; O0-NEXT: ll $[[R11:[0-9]+]], 0($[[R10]]) 227 228; ALL: $[[BB0:[A-Z_0-9]+]]: 229; ALL: ll $[[R12:[0-9]+]], 0($[[R2]]) 230; ALL: and $[[R13:[0-9]+]], $[[R12]], $[[R9]] 231; ALL: nor $[[R14:[0-9]+]], $zero, $[[R13]] 232; ALL: and $[[R15:[0-9]+]], $[[R14]], $[[R7]] 233; ALL: and $[[R16:[0-9]+]], $[[R12]], $[[R8]] 234; ALL: or $[[R17:[0-9]+]], $[[R16]], $[[R15]] 235; ALL: sc $[[R17]], 0($[[R2]]) 236; NOT-MICROMIPS: beqz $[[R17]], $[[BB0]] 237; MICROMIPS: beqzc $[[R17]], $[[BB0]] 238; MIPSR6: beqzc $[[R17]], $[[BB0]] 239 240; ALL: and $[[R18:[0-9]+]], $[[R12]], $[[R7]] 241; ALL: srlv $[[R19:[0-9]+]], $[[R18]], $[[R5]] 242 243; NO-SEB-SEH: sll $[[R20:[0-9]+]], $[[R19]], 24 244; NO-SEB-SEH: sra $2, $[[R20]], 24 245 246; HAS-SEB-SEH: seb $2, $[[R19]] 247} 248 249define signext i8 @AtomicSwap8(i8 signext %newval) nounwind { 250entry: 251 %0 = atomicrmw xchg i8* @y, i8 %newval monotonic 252 ret i8 %0 253 254; ALL-LABEL: AtomicSwap8: 255 256; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(y) 257; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(y)( 258 259; ALL: addiu $[[R1:[0-9]+]], $zero, -4 260; ALL: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] 261; ALL: andi $[[R3:[0-9]+]], $[[R0]], 3 262; CHECK-EL: sll $[[R5:[0-9]+]], $[[R3]], 3 263; CHECK-EB: xori $[[R4:[0-9]+]], $[[R3]], 3 264; CHECK-EB: sll $[[R5:[0-9]+]], $[[R4]], 3 265; ALL: ori $[[R6:[0-9]+]], $zero, 255 266; ALL: sllv $[[R7:[0-9]+]], $[[R6]], $[[R5]] 267; ALL: nor $[[R8:[0-9]+]], $zero, $[[R7]] 268; ALL: sllv $[[R9:[0-9]+]], $4, $[[R5]] 269 270; ALL: $[[BB0:[A-Z_0-9]+]]: 271; ALL: ll $[[R10:[0-9]+]], 0($[[R2]]) 272; ALL: and $[[R18:[0-9]+]], $[[R9]], $[[R7]] 273; ALL: and $[[R13:[0-9]+]], $[[R10]], $[[R8]] 274; ALL: or $[[R14:[0-9]+]], $[[R13]], $[[R18]] 275; ALL: sc $[[R14]], 0($[[R2]]) 276; NOT-MICROMIPS: beqz $[[R14]], $[[BB0]] 277; MICROMIPS: beqzc $[[R14]], $[[BB0]] 278; MIPSR6: beqzc $[[R14]], $[[BB0]] 279 280; ALL: and $[[R15:[0-9]+]], $[[R10]], $[[R7]] 281; ALL: srlv $[[R16:[0-9]+]], $[[R15]], $[[R5]] 282 283; NO-SEB-SEH: sll $[[R17:[0-9]+]], $[[R16]], 24 284; NO-SEB-SEH: sra $2, $[[R17]], 24 285 286; HAS-SEB-SEH: seb $2, $[[R16]] 287 288} 289 290define signext i8 @AtomicCmpSwap8(i8 signext %oldval, i8 signext %newval) nounwind { 291entry: 292 %pair0 = cmpxchg i8* @y, i8 %oldval, i8 %newval monotonic monotonic 293 %0 = extractvalue { i8, i1 } %pair0, 0 294 ret i8 %0 295 296; ALL-LABEL: AtomicCmpSwap8: 297 298; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(y) 299; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(y)( 300 301; ALL: addiu $[[R1:[0-9]+]], $zero, -4 302; ALL: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] 303; ALL: andi $[[R3:[0-9]+]], $[[R0]], 3 304; CHECK-EL: sll $[[R5:[0-9]+]], $[[R3]], 3 305; CHECK-EB: xori $[[R4:[0-9]+]], $[[R3]], 3 306; CHECK-EB: sll $[[R5:[0-9]+]], $[[R4]], 3 307; ALL: ori $[[R6:[0-9]+]], $zero, 255 308; ALL: sllv $[[R7:[0-9]+]], $[[R6]], $[[R5]] 309; ALL: nor $[[R8:[0-9]+]], $zero, $[[R7]] 310; ALL: andi $[[R9:[0-9]+]], $4, 255 311; ALL: sllv $[[R10:[0-9]+]], $[[R9]], $[[R5]] 312; ALL: andi $[[R11:[0-9]+]], $5, 255 313; ALL: sllv $[[R12:[0-9]+]], $[[R11]], $[[R5]] 314 315; ALL: $[[BB0:[A-Z_0-9]+]]: 316; ALL: ll $[[R13:[0-9]+]], 0($[[R2]]) 317; ALL: and $[[R14:[0-9]+]], $[[R13]], $[[R7]] 318; NOT-MICROMIPS: bne $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]] 319; MICROMIPS: bne $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]] 320; MIPSR6: bnec $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]] 321 322; ALL: and $[[R15:[0-9]+]], $[[R13]], $[[R8]] 323; ALL: or $[[R16:[0-9]+]], $[[R15]], $[[R12]] 324; ALL: sc $[[R16]], 0($[[R2]]) 325; NOT-MICROMIPS: beqz $[[R16]], $[[BB0]] 326; MICROMIPS: beqzc $[[R16]], $[[BB0]] 327; MIPSR6: beqzc $[[R16]], $[[BB0]] 328 329; ALL: $[[BB1]]: 330; ALL: srlv $[[R17:[0-9]+]], $[[R14]], $[[R5]] 331 332; NO-SEB-SEH: sll $[[R18:[0-9]+]], $[[R17]], 24 333; NO-SEB-SEH: sra $2, $[[R18]], 24 334 335; HAS-SEB-SEH: seb $2, $[[R17]] 336} 337 338define i1 @AtomicCmpSwapRes8(i8* %ptr, i8 signext %oldval, i8 signext %newval) nounwind { 339entry: 340 %0 = cmpxchg i8* %ptr, i8 %oldval, i8 %newval monotonic monotonic 341 %1 = extractvalue { i8, i1 } %0, 1 342 ret i1 %1 343; ALL-LABEL: AtomicCmpSwapRes8 344 345; ALL: addiu $[[R1:[0-9]+]], $zero, -4 346; ALL: and $[[R2:[0-9]+]], $4, $[[R1]] 347; ALL: andi $[[R3:[0-9]+]], $4, 3 348; CHECK-EL: sll $[[R5:[0-9]+]], $[[R3]], 3 349; CHECK-EB: xori $[[R4:[0-9]+]], $[[R3]], 3 350; CHECK-EB: sll $[[R5:[0-9]+]], $[[R4]], 3 351; ALL: ori $[[R6:[0-9]+]], $zero, 255 352; ALL: sllv $[[R7:[0-9]+]], $[[R6]], $[[R5]] 353; ALL: nor $[[R8:[0-9]+]], $zero, $[[R7]] 354; ALL: andi $[[R9:[0-9]+]], $5, 255 355; ALL: sllv $[[R10:[0-9]+]], $[[R9]], $[[R5]] 356; ALL: andi $[[R11:[0-9]+]], $6, 255 357; ALL: sllv $[[R12:[0-9]+]], $[[R11]], $[[R5]] 358 359; ALL: $[[BB0:[A-Z_0-9]+]]: 360; ALL: ll $[[R13:[0-9]+]], 0($[[R2]]) 361; ALL: and $[[R14:[0-9]+]], $[[R13]], $[[R7]] 362; NOT-MICROMIPS: bne $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]] 363; MICROMIPS: bne $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]] 364; MIPSR6: bnec $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]] 365 366; ALL: and $[[R15:[0-9]+]], $[[R13]], $[[R8]] 367; ALL: or $[[R16:[0-9]+]], $[[R15]], $[[R12]] 368; ALL: sc $[[R16]], 0($[[R2]]) 369; NOT-MICROMIPS: beqz $[[R16]], $[[BB0]] 370; MICROMIPS: beqzc $[[R16]], $[[BB0]] 371; MIPSR6: beqzc $[[R16]], $[[BB0]] 372 373; ALL: $[[BB1]]: 374; ALL: srlv $[[R17:[0-9]+]], $[[R14]], $[[R5]] 375 376; NO-SEB-SEH: sll $[[R18:[0-9]+]], $[[R17]], 24 377; NO-SEB-SEH: sra $[[R19:[0-9]+]], $[[R18]], 24 378 379; FIXME: -march=mips produces a redundant sign extension here... 380; NO-SEB-SEH: sll $[[R20:[0-9]+]], $5, 24 381; NO-SEB-SEH: sra $[[R20]], $[[R20]], 24 382 383; HAS-SEB-SEH: seb $[[R19:[0-9]+]], $[[R17]] 384 385; FIXME: ...Leading to this split check. 386; NO-SEB-SEH: xor $[[R21:[0-9]+]], $[[R19]], $[[R20]] 387; HAS-SEB-SEH: xor $[[R21:[0-9]+]], $[[R19]], $5 388 389; ALL: sltiu $2, $[[R21]], 1 390} 391 392; Check one i16 so that we cover the seh sign extend 393@z = common global i16 0, align 1 394 395define signext i16 @AtomicLoadAdd16(i16 signext %incr) nounwind { 396entry: 397 %0 = atomicrmw add i16* @z, i16 %incr monotonic 398 ret i16 %0 399 400; ALL-LABEL: AtomicLoadAdd16: 401 402; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(z) 403; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(z)( 404 405; ALL: addiu $[[R1:[0-9]+]], $zero, -4 406; ALL: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] 407; ALL: andi $[[R3:[0-9]+]], $[[R0]], 3 408; CHECK-EB: xori $[[R4:[0-9]+]], $[[R3]], 2 409; CHECK-EB: sll $[[R5:[0-9]+]], $[[R4]], 3 410; CHECK-EL: sll $[[R5:[0-9]+]], $[[R3]], 3 411; ALL: ori $[[R6:[0-9]+]], $zero, 65535 412; ALL: sllv $[[R7:[0-9]+]], $[[R6]], $[[R5]] 413; ALL: nor $[[R8:[0-9]+]], $zero, $[[R7]] 414; ALL: sllv $[[R9:[0-9]+]], $4, $[[R5]] 415 416; O0: $[[BB0:[A-Z_0-9]+]]: 417; O0: ld $[[R10:[0-9]+]] 418; O0-NEXT: ll $[[R11:[0-9]+]], 0($[[R10]]) 419 420; ALL: $[[BB0:[A-Z_0-9]+]]: 421; ALL: ll $[[R12:[0-9]+]], 0($[[R2]]) 422; ALL: addu $[[R13:[0-9]+]], $[[R12]], $[[R9]] 423; ALL: and $[[R14:[0-9]+]], $[[R13]], $[[R7]] 424; ALL: and $[[R15:[0-9]+]], $[[R12]], $[[R8]] 425; ALL: or $[[R16:[0-9]+]], $[[R15]], $[[R14]] 426; ALL: sc $[[R16]], 0($[[R2]]) 427; NOT-MICROMIPS: beqz $[[R16]], $[[BB0]] 428; MICROMIPS: beqzc $[[R16]], $[[BB0]] 429; MIPSR6: beqzc $[[R16]], $[[BB0]] 430 431; ALL: and $[[R17:[0-9]+]], $[[R12]], $[[R7]] 432; ALL: srlv $[[R18:[0-9]+]], $[[R17]], $[[R5]] 433 434; NO-SEB-SEH: sll $[[R19:[0-9]+]], $[[R18]], 16 435; NO-SEB-SEH: sra $2, $[[R19]], 16 436 437; MIPS32R2: seh $2, $[[R18]] 438} 439 440; Test that the i16 return value from cmpxchg is recognised as signed, 441; so that setCC doesn't end up comparing an unsigned value to a signed 442; value. 443; The rest of the functions here are testing the atomic expansion, so 444; we just match the end of the function. 445define {i16, i1} @foo(i16* %addr, i16 %l, i16 %r, i16 %new) { 446 %desired = add i16 %l, %r 447 %res = cmpxchg i16* %addr, i16 %desired, i16 %new seq_cst seq_cst 448 ret {i16, i1} %res 449 450; ALL-LABEL: foo 451; MIPSR6: addu $[[R2:[0-9]+]], $[[R1:[0-9]+]], $[[R0:[0-9]+]] 452; NOT-MICROMIPS: addu $[[R2:[0-9]+]], $[[R1:[0-9]+]], $[[R0:[0-9]+]] 453; MICROMIPS: addu16 $[[R2:[0-9]+]], $[[R1:[0-9]+]], $[[R0:[0-9]+]] 454 455; ALL: sync 456 457; ALL: andi $[[R3:[0-9]+]], $[[R2]], 65535 458; ALL: $[[BB0:[A-Z_0-9]+]]: 459; ALL: ll $[[R4:[0-9]+]], 0($[[R5:[0-9]+]]) 460; ALL: and $[[R6:[0-9]+]], $[[R4]], $ 461; ALL: and $[[R7:[0-9]+]], $[[R4]], $ 462; ALL: or $[[R8:[0-9]+]], $[[R7]], $ 463; ALL: sc $[[R8]], 0($[[R5]]) 464; NOT-MICROMIPS: beqz $[[R8]], $[[BB0]] 465; MICROMIPS: beqzc $[[R8]], $[[BB0]] 466; MIPSR6: beqzc $[[R8]], $[[BB0]] 467 468; ALL: srlv $[[R9:[0-9]+]], $[[R6]], $ 469 470; NO-SEB-SEH: sll $[[R10:[0-9]+]], $[[R9]], 16 471; NO-SEB-SEH: sra $[[R11:[0-9]+]], $[[R10]], 16 472 473; NO-SEB-SEH: sll $[[R12:[0-9]+]], $[[R2]], 16 474; NO-SEB-SEH: sra $[[R13:[0-9]+]], $[[R12]], 16 475 476; HAS-SEB-SEH: seh $[[R11:[0-9]+]], $[[R9]] 477; HAS-SEB-SEH: seh $[[R13:[0-9]+]], $[[R2]] 478 479; ALL: xor $[[R12:[0-9]+]], $[[R11]], $[[R13]] 480; ALL: sltiu $3, $[[R12]], 1 481; ALL: sync 482} 483 484@countsint = common global i32 0, align 4 485 486define i32 @CheckSync(i32 signext %v) nounwind noinline { 487entry: 488 %0 = atomicrmw add i32* @countsint, i32 %v seq_cst 489 ret i32 %0 490 491; ALL-LABEL: CheckSync: 492 493; ALL: sync 494; ALL: ll 495; ALL: sc 496; ALL: beq 497; ALL: sync 498} 499 500; make sure that this assertion in 501; TwoAddressInstructionPass::TryInstructionTransform does not fail: 502; 503; line 1203: assert(TargetRegisterInfo::isVirtualRegister(regB) && 504; 505; it failed when MipsDAGToDAGISel::ReplaceUsesWithZeroReg replaced an 506; operand of an atomic instruction with register $zero. 507@a = external global i32 508 509define i32 @zeroreg() nounwind { 510entry: 511 %pair0 = cmpxchg i32* @a, i32 1, i32 0 seq_cst seq_cst 512 %0 = extractvalue { i32, i1 } %pair0, 0 513 %1 = icmp eq i32 %0, 1 514 %conv = zext i1 %1 to i32 515 ret i32 %conv 516} 517 518; Check that MIPS32R6 has the correct offset range. 519; FIXME: At the moment, we don't seem to do addr+offset for any atomic load/store. 520define i32 @AtomicLoadAdd32_OffGt9Bit(i32 signext %incr) nounwind { 521entry: 522 %0 = atomicrmw add i32* getelementptr(i32, i32* @x, i32 256), i32 %incr monotonic 523 ret i32 %0 524 525; ALL-LABEL: AtomicLoadAdd32_OffGt9Bit: 526 527; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(x) 528; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(x)( 529 530; ALL: addiu $[[PTR:[0-9]+]], $[[R0]], 1024 531; ALL: $[[BB0:[A-Z_0-9]+]]: 532; ALL: ll $[[R1:[0-9]+]], 0($[[PTR]]) 533; ALL: addu $[[R2:[0-9]+]], $[[R1]], $4 534; ALL: sc $[[R2]], 0($[[PTR]]) 535; NOT-MICROMIPS: beqz $[[R2]], $[[BB0]] 536; MICROMIPS: beqzc $[[R2]], $[[BB0]] 537; MIPSR6: beqzc $[[R2]], $[[BB0]] 538} 539