; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=arm-eabi -mattr=+v6 %s -o - | FileCheck %s


target triple = "nvptx64-nvidia-cuda"

define i32 @test_simple_rotl(i32 %x) {
; CHECK-LABEL: test_simple_rotl:
; CHECK:       @ %bb.0:
; CHECK-NEXT:    ror r0, r0, #25
; CHECK-NEXT:    bx lr
  %shl = shl i32 %x, 7
  %shr = lshr i32 %x, 25
  %add = add i32 %shl, %shr
  ret i32 %add
}

define i32 @test_simple_rotr(i32 %x) {
; CHECK-LABEL: test_simple_rotr:
; CHECK:       @ %bb.0:
; CHECK-NEXT:    ror r0, r0, #7
; CHECK-NEXT:    bx lr
  %shr = lshr i32 %x, 7
  %shl = shl i32 %x, 25
  %add = add i32 %shr, %shl
  ret i32 %add
}

define i32 @test_rotl_var(i32 %x, i32 %y) {
; CHECK-LABEL: test_rotl_var:
; CHECK:       @ %bb.0:
; CHECK-NEXT:    rsb r1, r1, #32
; CHECK-NEXT:    ror r0, r0, r1
; CHECK-NEXT:    bx lr
  %shl = shl i32 %x, %y
  %sub = sub i32 32, %y
  %shr = lshr i32 %x, %sub
  %add = add i32 %shl, %shr
  ret i32 %add
}

define i32 @test_rotr_var(i32 %x, i32 %y) {
; CHECK-LABEL: test_rotr_var:
; CHECK:       @ %bb.0:
; CHECK-NEXT:    ror r0, r0, r1
; CHECK-NEXT:    bx lr
  %shr = lshr i32 %x, %y
  %sub = sub i32 32, %y
  %shl = shl i32 %x, %sub
  %add = add i32 %shr, %shl
  ret i32 %add
}

define i32 @test_invalid_rotl_var_and(i32 %x, i32 %y) {
; CHECK-LABEL: test_invalid_rotl_var_and:
; CHECK:       @ %bb.0:
; CHECK-NEXT:    rsb r2, r1, #0
; CHECK-NEXT:    and r2, r2, #31
; CHECK-NEXT:    lsr r2, r0, r2
; CHECK-NEXT:    add r0, r2, r0, lsl r1
; CHECK-NEXT:    bx lr
  %shr = shl i32 %x, %y
  %sub = sub nsw i32 0, %y
  %and = and i32 %sub, 31
  %shl = lshr i32 %x, %and
  %add = add i32 %shl, %shr
  ret i32 %add
}

define i32 @test_invalid_rotr_var_and(i32 %x, i32 %y) {
; CHECK-LABEL: test_invalid_rotr_var_and:
; CHECK:       @ %bb.0:
; CHECK-NEXT:    lsr r2, r0, r1
; CHECK-NEXT:    rsb r1, r1, #0
; CHECK-NEXT:    and r1, r1, #31
; CHECK-NEXT:    add r0, r2, r0, lsl r1
; CHECK-NEXT:    bx lr
  %shr = lshr i32 %x, %y
  %sub = sub nsw i32 0, %y
  %and = and i32 %sub, 31
  %shl = shl i32 %x, %and
  %add = add i32 %shr, %shl
  ret i32 %add
}

define i32 @test_fshl_special_case(i32 %x0, i32 %x1, i32 %y) {
; CHECK-LABEL: test_fshl_special_case:
; CHECK:       @ %bb.0:
; CHECK-NEXT:    lsl r0, r0, r2
; CHECK-NEXT:    eor r2, r2, #31
; CHECK-NEXT:    lsr r1, r1, #1
; CHECK-NEXT:    add r0, r0, r1, lsr r2
; CHECK-NEXT:    bx lr
  %shl = shl i32 %x0, %y
  %srli = lshr i32 %x1, 1
  %x = xor i32 %y, 31
  %srlo = lshr i32 %srli, %x
  %o = add i32 %shl, %srlo
  ret i32 %o
}

define i32 @test_fshr_special_case(i32 %x0, i32 %x1, i32 %y) {
; CHECK-LABEL: test_fshr_special_case:
; CHECK:       @ %bb.0:
; CHECK-NEXT:    lsr r1, r1, r2
; CHECK-NEXT:    eor r2, r2, #31
; CHECK-NEXT:    lsl r0, r0, #1
; CHECK-NEXT:    add r0, r1, r0, lsl r2
; CHECK-NEXT:    bx lr
  %shl = lshr i32 %x1, %y
  %srli = shl i32 %x0, 1
  %x = xor i32 %y, 31
  %srlo = shl i32 %srli, %x
  %o = add i32 %shl, %srlo
  ret i32 %o
}

define i64 @test_rotl_udiv_special_case(i64 %i) {
; CHECK-LABEL: test_rotl_udiv_special_case:
; CHECK:       @ %bb.0:
; CHECK-NEXT:    .save {r11, lr}
; CHECK-NEXT:    push {r11, lr}
; CHECK-NEXT:    adds r2, r0, r1
; CHECK-NEXT:    ldr r12, .LCPI8_0
; CHECK-NEXT:    adc lr, r2, #0
; CHECK-NEXT:    umull r3, r2, lr, r12
; CHECK-NEXT:    bic r3, r2, #1
; CHECK-NEXT:    add r2, r3, r2, lsr #1
; CHECK-NEXT:    ldr r3, .LCPI8_1
; CHECK-NEXT:    sub r2, lr, r2
; CHECK-NEXT:    subs r0, r0, r2
; CHECK-NEXT:    sbc r1, r1, #0
; CHECK-NEXT:    umull r2, lr, r0, r12
; CHECK-NEXT:    mla r0, r0, r3, lr
; CHECK-NEXT:    mla r0, r1, r12, r0
; CHECK-NEXT:    lsl r1, r2, #28
; CHECK-NEXT:    orr r1, r1, r0, lsr #4
; CHECK-NEXT:    lsl r0, r0, #28
; CHECK-NEXT:    orr r0, r0, r2, lsr #4
; CHECK-NEXT:    pop {r11, pc}
; CHECK-NEXT:    .p2align 2
; CHECK-NEXT:  @ %bb.1:
; CHECK-NEXT:  .LCPI8_0:
; CHECK-NEXT:    .long 2863311531 @ 0xaaaaaaab
; CHECK-NEXT:  .LCPI8_1:
; CHECK-NEXT:    .long 2863311530 @ 0xaaaaaaaa
  %lhs_div = udiv i64 %i, 3
  %rhs_div = udiv i64 %i, 48
  %lhs_shift = shl i64 %lhs_div, 60
  %out = add i64 %lhs_shift, %rhs_div
  ret i64 %out
}

define i32 @test_rotl_mul_special_case(i32 %i) {
; CHECK-LABEL: test_rotl_mul_special_case:
; CHECK:       @ %bb.0:
; CHECK-NEXT:    add r0, r0, r0, lsl #3
; CHECK-NEXT:    ror r0, r0, #25
; CHECK-NEXT:    bx lr
  %lhs_mul = mul i32 %i, 9
  %rhs_mul = mul i32 %i, 1152
  %lhs_shift = lshr i32 %lhs_mul, 25
  %out = add i32 %lhs_shift, %rhs_mul
  ret i32 %out
}

define i64 @test_rotl_mul_with_mask_special_case(i64 %i) {
; CHECK-LABEL: test_rotl_mul_with_mask_special_case:
; CHECK:       @ %bb.0:
; CHECK-NEXT:    mov r2, #9
; CHECK-NEXT:    add r1, r1, r1, lsl #3
; CHECK-NEXT:    umull r2, r3, r0, r2
; CHECK-NEXT:    and r0, r0, #1
; CHECK-NEXT:    lsl r0, r0, #7
; CHECK-NEXT:    add r1, r3, r1
; CHECK-NEXT:    orr r0, r0, r1, lsr #25
; CHECK-NEXT:    mov r1, #0
; CHECK-NEXT:    bx lr
  %lhs_mul = mul i64 %i, 1152
  %rhs_mul = mul i64 %i, 9
  %lhs_and = and i64 %lhs_mul, 160
  %rhs_shift = lshr i64 %rhs_mul, 57
  %out = add i64 %lhs_and, %rhs_shift
  ret i64 %out
}

define i32 @test_fshl_with_mask_special_case(i32 %x) {
; CHECK-LABEL: test_fshl_with_mask_special_case:
; CHECK:       @ %bb.0:
; CHECK-NEXT:    mov r1, #32
; CHECK-NEXT:    orr r0, r1, r0, ror #27
; CHECK-NEXT:    bic r0, r0, #30
; CHECK-NEXT:    bx lr
  %or1 = or i32 %x, 1
  %sh1 = shl i32 %or1, 5
  %sh2 = lshr i32 %x, 27
  %1 = and i32 %sh2, 1
  %r = add i32 %sh1, %1
  ret i32 %r
}
