; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; Make sure that a negative value for the compare-and-swap is zero extended
; from i8/i16 to i32 since it will be compared for equality.
; RUN: llc -mtriple=powerpc64le-linux-gnu -verify-machineinstrs < %s | FileCheck %s
; RUN: llc -mtriple=powerpc64le-linux-gnu -mcpu=pwr7 -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK-P7

@str = private unnamed_addr constant [46 x i8] c"FAILED: __atomic_compare_exchange_n() failed.\00"
@str.1 = private unnamed_addr constant [59 x i8] c"FAILED: __atomic_compare_exchange_n() set the wrong value.\00"
@str.2 = private unnamed_addr constant [7 x i8] c"PASSED\00"

define signext i32 @main() nounwind {
; CHECK-LABEL: main:
; CHECK:       # %bb.0: # %L.entry
; CHECK-NEXT:    mflr 0
; CHECK-NEXT:    stdu 1, -48(1)
; CHECK-NEXT:    li 3, -32477
; CHECK-NEXT:    std 0, 64(1)
; CHECK-NEXT:    sth 3, 46(1)
; CHECK-NEXT:    addi 3, 1, 46
; CHECK-NEXT:    lharx 4, 0, 3
; CHECK-NEXT:    cmplwi 4, 33059
; CHECK-NEXT:    bne- 0, .LBB0_4
; CHECK-NEXT:  # %bb.1: # %cmpxchg.fencedstore
; CHECK-NEXT:    sync
; CHECK-NEXT:    li 4, 234
; CHECK-NEXT:  .LBB0_2: # %cmpxchg.trystore
; CHECK-NEXT:    #
; CHECK-NEXT:    sthcx. 4, 0, 3
; CHECK-NEXT:    beq+ 0, .LBB0_5
; CHECK-NEXT:  # %bb.3: # %cmpxchg.releasedload
; CHECK-NEXT:    #
; CHECK-NEXT:    lharx 5, 0, 3
; CHECK-NEXT:    cmplwi 5, 33059
; CHECK-NEXT:    beq+ 0, .LBB0_2
; CHECK-NEXT:  .LBB0_4: # %cmpxchg.nostore
; CHECK-NEXT:    lwsync
; CHECK-NEXT:    crxor 20, 20, 20
; CHECK-NEXT:    b .LBB0_6
; CHECK-NEXT:  .LBB0_5: # %cmpxchg.success
; CHECK-NEXT:    lwsync
; CHECK-NEXT:    creqv 20, 20, 20
; CHECK-NEXT:  .LBB0_6: # %cmpxchg.end
; CHECK-NEXT:    bc 4, 20, .LBB0_9
; CHECK-NEXT:  # %bb.7: # %L.B0000
; CHECK-NEXT:    lhz 3, 46(1)
; CHECK-NEXT:    cmplwi 3, 234
; CHECK-NEXT:    bne 0, .LBB0_10
; CHECK-NEXT:  # %bb.8: # %L.B0001
; CHECK-NEXT:    addis 3, 2, .L_MergedGlobals@toc@ha
; CHECK-NEXT:    addi 3, 3, .L_MergedGlobals@toc@l
; CHECK-NEXT:    bl puts
; CHECK-NEXT:    nop
; CHECK-NEXT:    li 3, 0
; CHECK-NEXT:    b .LBB0_12
; CHECK-NEXT:  .LBB0_9: # %L.B0003
; CHECK-NEXT:    addis 3, 2, .L_MergedGlobals@toc@ha
; CHECK-NEXT:    addi 3, 3, .L_MergedGlobals@toc@l
; CHECK-NEXT:    addi 3, 3, 16
; CHECK-NEXT:    b .LBB0_11
; CHECK-NEXT:  .LBB0_10: # %L.B0005
; CHECK-NEXT:    addis 3, 2, .L_MergedGlobals@toc@ha
; CHECK-NEXT:    addi 3, 3, .L_MergedGlobals@toc@l
; CHECK-NEXT:    addi 3, 3, 64
; CHECK-NEXT:  .LBB0_11: # %L.B0003
; CHECK-NEXT:    bl puts
; CHECK-NEXT:    nop
; CHECK-NEXT:    li 3, 1
; CHECK-NEXT:  .LBB0_12: # %L.B0003
; CHECK-NEXT:    addi 1, 1, 48
; CHECK-NEXT:    ld 0, 16(1)
; CHECK-NEXT:    mtlr 0
; CHECK-NEXT:    blr
;
; CHECK-P7-LABEL: main:
; CHECK-P7:       # %bb.0: # %L.entry
; CHECK-P7-NEXT:    mflr 0
; CHECK-P7-NEXT:    stdu 1, -48(1)
; CHECK-P7-NEXT:    li 3, -32477
; CHECK-P7-NEXT:    addi 4, 1, 46
; CHECK-P7-NEXT:    std 0, 64(1)
; CHECK-P7-NEXT:    sth 3, 46(1)
; CHECK-P7-NEXT:    rldicr 3, 4, 0, 61
; CHECK-P7-NEXT:    rlwinm 4, 4, 3, 27, 27
; CHECK-P7-NEXT:    lwarx 5, 0, 3
; CHECK-P7-NEXT:    srw 6, 5, 4
; CHECK-P7-NEXT:    clrlwi 6, 6, 16
; CHECK-P7-NEXT:    cmplwi 6, 33059
; CHECK-P7-NEXT:    bne- 0, .LBB0_4
; CHECK-P7-NEXT:  # %bb.1: # %cmpxchg.fencedstore
; CHECK-P7-NEXT:    lis 6, 0
; CHECK-P7-NEXT:    li 7, 234
; CHECK-P7-NEXT:    sync
; CHECK-P7-NEXT:    ori 6, 6, 65535
; CHECK-P7-NEXT:    slw 7, 7, 4
; CHECK-P7-NEXT:    slw 6, 6, 4
; CHECK-P7-NEXT:    not 6, 6
; CHECK-P7-NEXT:  .LBB0_2: # %cmpxchg.trystore
; CHECK-P7-NEXT:    #
; CHECK-P7-NEXT:    and 5, 5, 6
; CHECK-P7-NEXT:    or 5, 5, 7
; CHECK-P7-NEXT:    stwcx. 5, 0, 3
; CHECK-P7-NEXT:    beq+ 0, .LBB0_5
; CHECK-P7-NEXT:  # %bb.3: # %cmpxchg.releasedload
; CHECK-P7-NEXT:    #
; CHECK-P7-NEXT:    lwarx 5, 0, 3
; CHECK-P7-NEXT:    srw 8, 5, 4
; CHECK-P7-NEXT:    clrlwi 8, 8, 16
; CHECK-P7-NEXT:    cmplwi 8, 33059
; CHECK-P7-NEXT:    beq+ 0, .LBB0_2
; CHECK-P7-NEXT:  .LBB0_4: # %cmpxchg.nostore
; CHECK-P7-NEXT:    crxor 20, 20, 20
; CHECK-P7-NEXT:    lwsync
; CHECK-P7-NEXT:    b .LBB0_6
; CHECK-P7-NEXT:  .LBB0_5: # %cmpxchg.success
; CHECK-P7-NEXT:    lwsync
; CHECK-P7-NEXT:    creqv 20, 20, 20
; CHECK-P7-NEXT:  .LBB0_6: # %cmpxchg.end
; CHECK-P7-NEXT:    bc 4, 20, .LBB0_9
; CHECK-P7-NEXT:  # %bb.7: # %L.B0000
; CHECK-P7-NEXT:    lhz 3, 46(1)
; CHECK-P7-NEXT:    cmplwi 3, 234
; CHECK-P7-NEXT:    bne 0, .LBB0_10
; CHECK-P7-NEXT:  # %bb.8: # %L.B0001
; CHECK-P7-NEXT:    addis 3, 2, .L_MergedGlobals@toc@ha
; CHECK-P7-NEXT:    addi 3, 3, .L_MergedGlobals@toc@l
; CHECK-P7-NEXT:    bl puts
; CHECK-P7-NEXT:    nop
; CHECK-P7-NEXT:    li 3, 0
; CHECK-P7-NEXT:    b .LBB0_12
; CHECK-P7-NEXT:  .LBB0_9: # %L.B0003
; CHECK-P7-NEXT:    addis 3, 2, .L_MergedGlobals@toc@ha
; CHECK-P7-NEXT:    addi 3, 3, .L_MergedGlobals@toc@l
; CHECK-P7-NEXT:    addi 3, 3, 16
; CHECK-P7-NEXT:    b .LBB0_11
; CHECK-P7-NEXT:  .LBB0_10: # %L.B0005
; CHECK-P7-NEXT:    addis 3, 2, .L_MergedGlobals@toc@ha
; CHECK-P7-NEXT:    addi 3, 3, .L_MergedGlobals@toc@l
; CHECK-P7-NEXT:    addi 3, 3, 64
; CHECK-P7-NEXT:  .LBB0_11: # %L.B0003
; CHECK-P7-NEXT:    bl puts
; CHECK-P7-NEXT:    nop
; CHECK-P7-NEXT:    li 3, 1
; CHECK-P7-NEXT:  .LBB0_12: # %L.B0003
; CHECK-P7-NEXT:    addi 1, 1, 48
; CHECK-P7-NEXT:    ld 0, 16(1)
; CHECK-P7-NEXT:    mtlr 0
; CHECK-P7-NEXT:    blr
L.entry:
  %value.addr = alloca i16, align 2
  store i16 -32477, ptr %value.addr, align 2
  %0 = cmpxchg ptr %value.addr, i16 -32477, i16 234 seq_cst seq_cst
  %1 = extractvalue { i16, i1 } %0, 1
  br i1 %1, label %L.B0000, label %L.B0003

L.B0003:                                          ; preds = %L.entry
  %puts = call i32 @puts(ptr @str)
  ret i32 1

L.B0000:                                          ; preds = %L.entry
  %2 = load i16, ptr %value.addr, align 2
  %3 = icmp eq i16 %2, 234
  br i1 %3, label %L.B0001, label %L.B0005

L.B0005:                                          ; preds = %L.B0000
  %puts1 = call i32 @puts(ptr @str.1)
  ret i32 1

L.B0001:                                          ; preds = %L.B0000
  %puts2 = call i32 @puts(ptr @str.2)
  ret i32 0
}

; Function Attrs: nounwind
declare i32 @puts(ptr nocapture readonly) #0
