| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py |
| ; RUN: llc < %s -mtriple=avr -mattr=movw -verify-machineinstrs | FileCheck %s |
| |
| define i32 @shl_i32_1(i32 %a) { |
| ; CHECK-LABEL: shl_i32_1: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: lsl r22 |
| ; CHECK-NEXT: rol r23 |
| ; CHECK-NEXT: rol r24 |
| ; CHECK-NEXT: rol r25 |
| ; CHECK-NEXT: ret |
| %res = shl i32 %a, 1 |
| ret i32 %res |
| } |
| |
| define i32 @shl_i32_2(i32 %a) { |
| ; CHECK-LABEL: shl_i32_2: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: lsl r22 |
| ; CHECK-NEXT: rol r23 |
| ; CHECK-NEXT: rol r24 |
| ; CHECK-NEXT: rol r25 |
| ; CHECK-NEXT: lsl r22 |
| ; CHECK-NEXT: rol r23 |
| ; CHECK-NEXT: rol r24 |
| ; CHECK-NEXT: rol r25 |
| ; CHECK-NEXT: ret |
| %res = shl i32 %a, 2 |
| ret i32 %res |
| } |
| |
| define i32 @shl_i32_4(i32 %a) { |
| ; CHECK-LABEL: shl_i32_4: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: swap r25 |
| ; CHECK-NEXT: andi r25, 240 |
| ; CHECK-NEXT: swap r24 |
| ; CHECK-NEXT: eor r25, r24 |
| ; CHECK-NEXT: andi r24, 240 |
| ; CHECK-NEXT: eor r25, r24 |
| ; CHECK-NEXT: swap r23 |
| ; CHECK-NEXT: eor r24, r23 |
| ; CHECK-NEXT: andi r23, 240 |
| ; CHECK-NEXT: eor r24, r23 |
| ; CHECK-NEXT: swap r22 |
| ; CHECK-NEXT: eor r23, r22 |
| ; CHECK-NEXT: andi r22, 240 |
| ; CHECK-NEXT: eor r23, r22 |
| ; CHECK-NEXT: ret |
| %res = shl i32 %a, 4 |
| ret i32 %res |
| } |
| |
| ; shift four bits and then shift one bit |
| define i32 @shl_i32_5(i32 %a) { |
| ; CHECK-LABEL: shl_i32_5: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: swap r25 |
| ; CHECK-NEXT: andi r25, 240 |
| ; CHECK-NEXT: swap r24 |
| ; CHECK-NEXT: eor r25, r24 |
| ; CHECK-NEXT: andi r24, 240 |
| ; CHECK-NEXT: eor r25, r24 |
| ; CHECK-NEXT: swap r23 |
| ; CHECK-NEXT: eor r24, r23 |
| ; CHECK-NEXT: andi r23, 240 |
| ; CHECK-NEXT: eor r24, r23 |
| ; CHECK-NEXT: swap r22 |
| ; CHECK-NEXT: eor r23, r22 |
| ; CHECK-NEXT: andi r22, 240 |
| ; CHECK-NEXT: eor r23, r22 |
| ; CHECK-NEXT: lsl r22 |
| ; CHECK-NEXT: rol r23 |
| ; CHECK-NEXT: rol r24 |
| ; CHECK-NEXT: rol r25 |
| ; CHECK-NEXT: ret |
| %res = shl i32 %a, 5 |
| ret i32 %res |
| } |
| |
| ; shift two to the right and move the registers around |
| define i32 @shl_i32_6(i32 %a) { |
| ; CHECK-LABEL: shl_i32_6: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: lsr r25 |
| ; CHECK-NEXT: ror r24 |
| ; CHECK-NEXT: ror r23 |
| ; CHECK-NEXT: ror r22 |
| ; CHECK-NEXT: mov r18, r1 |
| ; CHECK-NEXT: ror r18 |
| ; CHECK-NEXT: lsr r25 |
| ; CHECK-NEXT: ror r24 |
| ; CHECK-NEXT: ror r23 |
| ; CHECK-NEXT: ror r22 |
| ; CHECK-NEXT: ror r18 |
| ; CHECK-NEXT: mov r25, r24 |
| ; CHECK-NEXT: mov r24, r23 |
| ; CHECK-NEXT: mov r19, r22 |
| ; CHECK-NEXT: movw r22, r18 |
| ; CHECK-NEXT: ret |
| %res = shl i32 %a, 6 |
| ret i32 %res |
| } |
| |
| |
| ; shift one to the right and move registers around |
| define i32 @shl_i32_7(i32 %a) { |
| ; CHECK-LABEL: shl_i32_7: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: lsr r25 |
| ; CHECK-NEXT: ror r24 |
| ; CHECK-NEXT: ror r23 |
| ; CHECK-NEXT: ror r22 |
| ; CHECK-NEXT: mov r18, r1 |
| ; CHECK-NEXT: ror r18 |
| ; CHECK-NEXT: mov r25, r24 |
| ; CHECK-NEXT: mov r24, r23 |
| ; CHECK-NEXT: mov r19, r22 |
| ; CHECK-NEXT: movw r22, r18 |
| ; CHECK-NEXT: ret |
| %res = shl i32 %a, 7 |
| ret i32 %res |
| } |
| |
| define i32 @shl_i32_8(i32 %a) { |
| ; CHECK-LABEL: shl_i32_8: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: mov r25, r24 |
| ; CHECK-NEXT: mov r24, r23 |
| ; CHECK-NEXT: mov r23, r22 |
| ; CHECK-NEXT: mov r22, r1 |
| ; CHECK-NEXT: ret |
| %res = shl i32 %a, 8 |
| ret i32 %res |
| } |
| |
| define i32 @shl_i32_9(i32 %a) { |
| ; CHECK-LABEL: shl_i32_9: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: lsl r22 |
| ; CHECK-NEXT: rol r23 |
| ; CHECK-NEXT: rol r24 |
| ; CHECK-NEXT: mov r25, r24 |
| ; CHECK-NEXT: mov r24, r23 |
| ; CHECK-NEXT: mov r23, r22 |
| ; CHECK-NEXT: mov r22, r1 |
| ; CHECK-NEXT: ret |
| %res = shl i32 %a, 9 |
| ret i32 %res |
| } |
| |
| ; shift 3 of 4 registers and move the others around |
| define i32 @shl_i32_12(i32 %a) { |
| ; CHECK-LABEL: shl_i32_12: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: swap r24 |
| ; CHECK-NEXT: andi r24, 240 |
| ; CHECK-NEXT: swap r23 |
| ; CHECK-NEXT: eor r24, r23 |
| ; CHECK-NEXT: andi r23, 240 |
| ; CHECK-NEXT: eor r24, r23 |
| ; CHECK-NEXT: swap r22 |
| ; CHECK-NEXT: eor r23, r22 |
| ; CHECK-NEXT: andi r22, 240 |
| ; CHECK-NEXT: eor r23, r22 |
| ; CHECK-NEXT: mov r25, r24 |
| ; CHECK-NEXT: mov r24, r23 |
| ; CHECK-NEXT: mov r23, r22 |
| ; CHECK-NEXT: mov r22, r1 |
| ; CHECK-NEXT: ret |
| %res = shl i32 %a, 12 |
| ret i32 %res |
| } |
| |
| define i32 @shl_i32_15(i32 %a) { |
| ; CHECK-LABEL: shl_i32_15: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: movw r18, r22 |
| ; CHECK-NEXT: lsr r24 |
| ; CHECK-NEXT: ror r19 |
| ; CHECK-NEXT: ror r18 |
| ; CHECK-NEXT: mov r23, r1 |
| ; CHECK-NEXT: ror r23 |
| ; CHECK-NEXT: mov r22, r1 |
| ; CHECK-NEXT: movw r24, r18 |
| ; CHECK-NEXT: ret |
| %res = shl i32 %a, 15 |
| ret i32 %res |
| } |
| |
| ; This is a special case: this shift is performed directly inside SelectionDAG |
| ; instead of as a custom lowering like the other shift operations. |
| define i32 @shl_i32_16(i32 %a) { |
| ; CHECK-LABEL: shl_i32_16: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: movw r24, r22 |
| ; CHECK-NEXT: ldi r22, 0 |
| ; CHECK-NEXT: ldi r23, 0 |
| ; CHECK-NEXT: ret |
| %res = shl i32 %a, 16 |
| ret i32 %res |
| } |
| |
| ; Combined with the register allocator, shift instructions can sometimes be |
| ; optimized away entirely. The least significant registers are simply stored |
| ; directly instead of moving them first. |
| define void @shl_i32_16_ptr(i32 %a, ptr %ptr) { |
| ; CHECK-LABEL: shl_i32_16_ptr: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: movw r30, r20 |
| ; CHECK-NEXT: std Z+3, r23 |
| ; CHECK-NEXT: std Z+2, r22 |
| ; CHECK-NEXT: ldi r24, 0 |
| ; CHECK-NEXT: ldi r25, 0 |
| ; CHECK-NEXT: std Z+1, r25 |
| ; CHECK-NEXT: st Z, r24 |
| ; CHECK-NEXT: ret |
| %res = shl i32 %a, 16 |
| store i32 %res, ptr %ptr |
| ret void |
| } |
| |
| ; shift only the most significant byte and then move it |
| define i32 @shl_i32_28(i32 %a) { |
| ; CHECK-LABEL: shl_i32_28: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: swap r22 |
| ; CHECK-NEXT: andi r22, 240 |
| ; CHECK-NEXT: mov r25, r22 |
| ; CHECK-NEXT: mov r24, r1 |
| ; CHECK-NEXT: mov r23, r1 |
| ; CHECK-NEXT: mov r22, r1 |
| ; CHECK-NEXT: ret |
| %res = shl i32 %a, 28 |
| ret i32 %res |
| } |
| |
| ; move the rightmost bit to the leftmost bit and clear the rest |
| define i32 @shl_i32_31(i32 %a) { |
| ; CHECK-LABEL: shl_i32_31: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: lsr r22 |
| ; CHECK-NEXT: mov r25, r1 |
| ; CHECK-NEXT: ror r25 |
| ; CHECK-NEXT: mov r24, r1 |
| ; CHECK-NEXT: mov r23, r1 |
| ; CHECK-NEXT: mov r22, r1 |
| ; CHECK-NEXT: ret |
| %res = shl i32 %a, 31 |
| ret i32 %res |
| } |
| |
| define i32 @lshr_i32_1(i32 %a) { |
| ; CHECK-LABEL: lshr_i32_1: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: lsr r25 |
| ; CHECK-NEXT: ror r24 |
| ; CHECK-NEXT: ror r23 |
| ; CHECK-NEXT: ror r22 |
| ; CHECK-NEXT: ret |
| %res = lshr i32 %a, 1 |
| ret i32 %res |
| } |
| |
| define i32 @lshr_i32_2(i32 %a) { |
| ; CHECK-LABEL: lshr_i32_2: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: lsr r25 |
| ; CHECK-NEXT: ror r24 |
| ; CHECK-NEXT: ror r23 |
| ; CHECK-NEXT: ror r22 |
| ; CHECK-NEXT: lsr r25 |
| ; CHECK-NEXT: ror r24 |
| ; CHECK-NEXT: ror r23 |
| ; CHECK-NEXT: ror r22 |
| ; CHECK-NEXT: ret |
| %res = lshr i32 %a, 2 |
| ret i32 %res |
| } |
| |
| define i32 @lshr_i32_4(i32 %a) { |
| ; CHECK-LABEL: lshr_i32_4: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: swap r22 |
| ; CHECK-NEXT: andi r22, 15 |
| ; CHECK-NEXT: swap r23 |
| ; CHECK-NEXT: eor r22, r23 |
| ; CHECK-NEXT: andi r23, 15 |
| ; CHECK-NEXT: eor r22, r23 |
| ; CHECK-NEXT: swap r24 |
| ; CHECK-NEXT: eor r23, r24 |
| ; CHECK-NEXT: andi r24, 15 |
| ; CHECK-NEXT: eor r23, r24 |
| ; CHECK-NEXT: swap r25 |
| ; CHECK-NEXT: eor r24, r25 |
| ; CHECK-NEXT: andi r25, 15 |
| ; CHECK-NEXT: eor r24, r25 |
| ; CHECK-NEXT: ret |
| %res = lshr i32 %a, 4 |
| ret i32 %res |
| } |
| |
| define i32 @lshr_i32_6(i32 %a) { |
| ; CHECK-LABEL: lshr_i32_6: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: lsl r22 |
| ; CHECK-NEXT: rol r23 |
| ; CHECK-NEXT: rol r24 |
| ; CHECK-NEXT: rol r25 |
| ; CHECK-NEXT: mov r19, r1 |
| ; CHECK-NEXT: rol r19 |
| ; CHECK-NEXT: lsl r22 |
| ; CHECK-NEXT: rol r23 |
| ; CHECK-NEXT: rol r24 |
| ; CHECK-NEXT: rol r25 |
| ; CHECK-NEXT: rol r19 |
| ; CHECK-NEXT: mov r22, r23 |
| ; CHECK-NEXT: mov r23, r24 |
| ; CHECK-NEXT: mov r18, r25 |
| ; CHECK-NEXT: movw r24, r18 |
| ; CHECK-NEXT: ret |
| %res = lshr i32 %a, 6 |
| ret i32 %res |
| } |
| |
| define i32 @lshr_i32_7(i32 %a) { |
| ; CHECK-LABEL: lshr_i32_7: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: lsl r22 |
| ; CHECK-NEXT: rol r23 |
| ; CHECK-NEXT: rol r24 |
| ; CHECK-NEXT: rol r25 |
| ; CHECK-NEXT: mov r19, r1 |
| ; CHECK-NEXT: rol r19 |
| ; CHECK-NEXT: mov r22, r23 |
| ; CHECK-NEXT: mov r23, r24 |
| ; CHECK-NEXT: mov r18, r25 |
| ; CHECK-NEXT: movw r24, r18 |
| ; CHECK-NEXT: ret |
| %res = lshr i32 %a, 7 |
| ret i32 %res |
| } |
| |
| define i32 @lshr_i32_8(i32 %a) { |
| ; CHECK-LABEL: lshr_i32_8: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: mov r22, r23 |
| ; CHECK-NEXT: mov r23, r24 |
| ; CHECK-NEXT: mov r24, r25 |
| ; CHECK-NEXT: mov r25, r1 |
| ; CHECK-NEXT: ret |
| %res = lshr i32 %a, 8 |
| ret i32 %res |
| } |
| |
| define i32 @lshr_i32_9(i32 %a) { |
| ; CHECK-LABEL: lshr_i32_9: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: lsr r25 |
| ; CHECK-NEXT: ror r24 |
| ; CHECK-NEXT: ror r23 |
| ; CHECK-NEXT: mov r22, r23 |
| ; CHECK-NEXT: mov r23, r24 |
| ; CHECK-NEXT: mov r24, r25 |
| ; CHECK-NEXT: mov r25, r1 |
| ; CHECK-NEXT: ret |
| %res = lshr i32 %a, 9 |
| ret i32 %res |
| } |
| |
| define i32 @lshr_i32_16(i32 %a) { |
| ; CHECK-LABEL: lshr_i32_16: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: movw r22, r24 |
| ; CHECK-NEXT: ldi r24, 0 |
| ; CHECK-NEXT: ldi r25, 0 |
| ; CHECK-NEXT: ret |
| %res = lshr i32 %a, 16 |
| ret i32 %res |
| } |
| |
| define i32 @lshr_i32_24(i32 %a) { |
| ; CHECK-LABEL: lshr_i32_24: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: mov r22, r25 |
| ; CHECK-NEXT: mov r23, r1 |
| ; CHECK-NEXT: mov r24, r1 |
| ; CHECK-NEXT: mov r25, r1 |
| ; CHECK-NEXT: ret |
| %res = lshr i32 %a, 24 |
| ret i32 %res |
| } |
| |
| define i32 @lshr_i32_31(i32 %a) { |
| ; CHECK-LABEL: lshr_i32_31: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: lsl r25 |
| ; CHECK-NEXT: mov r22, r1 |
| ; CHECK-NEXT: rol r22 |
| ; CHECK-NEXT: mov r23, r1 |
| ; CHECK-NEXT: mov r24, r1 |
| ; CHECK-NEXT: mov r25, r1 |
| ; CHECK-NEXT: ret |
| %res = lshr i32 %a, 31 |
| ret i32 %res |
| } |
| |
| define i32 @ashr_i32_1(i32 %a) { |
| ; CHECK-LABEL: ashr_i32_1: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: asr r25 |
| ; CHECK-NEXT: ror r24 |
| ; CHECK-NEXT: ror r23 |
| ; CHECK-NEXT: ror r22 |
| ; CHECK-NEXT: ret |
| %res = ashr i32 %a, 1 |
| ret i32 %res |
| } |
| |
| define i32 @ashr_i32_2(i32 %a) { |
| ; CHECK-LABEL: ashr_i32_2: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: asr r25 |
| ; CHECK-NEXT: ror r24 |
| ; CHECK-NEXT: ror r23 |
| ; CHECK-NEXT: ror r22 |
| ; CHECK-NEXT: asr r25 |
| ; CHECK-NEXT: ror r24 |
| ; CHECK-NEXT: ror r23 |
| ; CHECK-NEXT: ror r22 |
| ; CHECK-NEXT: ret |
| %res = ashr i32 %a, 2 |
| ret i32 %res |
| } |
| |
| ; can't use the swap/andi/eor trick here |
| define i32 @ashr_i32_4(i32 %a) { |
| ; CHECK-LABEL: ashr_i32_4: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: asr r25 |
| ; CHECK-NEXT: ror r24 |
| ; CHECK-NEXT: ror r23 |
| ; CHECK-NEXT: ror r22 |
| ; CHECK-NEXT: asr r25 |
| ; CHECK-NEXT: ror r24 |
| ; CHECK-NEXT: ror r23 |
| ; CHECK-NEXT: ror r22 |
| ; CHECK-NEXT: asr r25 |
| ; CHECK-NEXT: ror r24 |
| ; CHECK-NEXT: ror r23 |
| ; CHECK-NEXT: ror r22 |
| ; CHECK-NEXT: asr r25 |
| ; CHECK-NEXT: ror r24 |
| ; CHECK-NEXT: ror r23 |
| ; CHECK-NEXT: ror r22 |
| ; CHECK-NEXT: ret |
| %res = ashr i32 %a, 4 |
| ret i32 %res |
| } |
| |
| define i32 @ashr_i32_7(i32 %a) { |
| ; CHECK-LABEL: ashr_i32_7: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: lsl r22 |
| ; CHECK-NEXT: rol r23 |
| ; CHECK-NEXT: rol r24 |
| ; CHECK-NEXT: rol r25 |
| ; CHECK-NEXT: sbc r19, r19 |
| ; CHECK-NEXT: mov r22, r23 |
| ; CHECK-NEXT: mov r23, r24 |
| ; CHECK-NEXT: mov r18, r25 |
| ; CHECK-NEXT: movw r24, r18 |
| ; CHECK-NEXT: ret |
| %res = ashr i32 %a, 7 |
| ret i32 %res |
| } |
| |
| ; TODO: this could be optimized to 4 movs, instead of 5. |
| define i32 @ashr_i32_8(i32 %a) { |
| ; CHECK-LABEL: ashr_i32_8: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: mov r19, r25 |
| ; CHECK-NEXT: lsl r19 |
| ; CHECK-NEXT: sbc r19, r19 |
| ; CHECK-NEXT: mov r22, r23 |
| ; CHECK-NEXT: mov r23, r24 |
| ; CHECK-NEXT: mov r18, r25 |
| ; CHECK-NEXT: movw r24, r18 |
| ; CHECK-NEXT: ret |
| %res = ashr i32 %a, 8 |
| ret i32 %res |
| } |
| |
| define i32 @ashr_i32_16(i32 %a) { |
| ; CHECK-LABEL: ashr_i32_16: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: movw r22, r24 |
| ; CHECK-NEXT: lsl r25 |
| ; CHECK-NEXT: sbc r25, r25 |
| ; CHECK-NEXT: mov r24, r25 |
| ; CHECK-NEXT: ret |
| %res = ashr i32 %a, 16 |
| ret i32 %res |
| } |
| |
| define i32 @ashr_i32_17(i32 %a) { |
| ; CHECK-LABEL: ashr_i32_17: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: movw r22, r24 |
| ; CHECK-NEXT: lsl r25 |
| ; CHECK-NEXT: sbc r25, r25 |
| ; CHECK-NEXT: asr r23 |
| ; CHECK-NEXT: ror r22 |
| ; CHECK-NEXT: mov r24, r25 |
| ; CHECK-NEXT: ret |
| %res = ashr i32 %a, 17 |
| ret i32 %res |
| } |
| |
| define i32 @ashr_i32_22(i32 %a) { |
| ; CHECK-LABEL: ashr_i32_22: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: lsl r24 |
| ; CHECK-NEXT: rol r25 |
| ; CHECK-NEXT: sbc r18, r18 |
| ; CHECK-NEXT: lsl r24 |
| ; CHECK-NEXT: rol r25 |
| ; CHECK-NEXT: mov r19, r18 |
| ; CHECK-NEXT: mov r23, r18 |
| ; CHECK-NEXT: rol r23 |
| ; CHECK-NEXT: mov r22, r25 |
| ; CHECK-NEXT: movw r24, r18 |
| ; CHECK-NEXT: ret |
| %res = ashr i32 %a, 22 |
| ret i32 %res |
| } |
| |
| define i32 @ashr_i32_23(i32 %a) { |
| ; CHECK-LABEL: ashr_i32_23: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: lsl r24 |
| ; CHECK-NEXT: rol r25 |
| ; CHECK-NEXT: sbc r23, r23 |
| ; CHECK-NEXT: mov r22, r25 |
| ; CHECK-NEXT: mov r24, r23 |
| ; CHECK-NEXT: mov r25, r23 |
| ; CHECK-NEXT: ret |
| %res = ashr i32 %a, 23 |
| ret i32 %res |
| } |
| |
| define i32 @ashr_i32_30(i32 %a) { |
| ; CHECK-LABEL: ashr_i32_30: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: lsl r25 |
| ; CHECK-NEXT: sbc r23, r23 |
| ; CHECK-NEXT: lsl r25 |
| ; CHECK-NEXT: mov r22, r23 |
| ; CHECK-NEXT: rol r22 |
| ; CHECK-NEXT: mov r24, r23 |
| ; CHECK-NEXT: mov r25, r23 |
| ; CHECK-NEXT: ret |
| %res = ashr i32 %a, 30 |
| ret i32 %res |
| } |
| |
| define i32 @ashr_i32_31(i32 %a) { |
| ; CHECK-LABEL: ashr_i32_31: |
| ; CHECK: ; %bb.0: |
| ; CHECK-NEXT: lsl r25 |
| ; CHECK-NEXT: sbc r22, r22 |
| ; CHECK-NEXT: mov r23, r22 |
| ; CHECK-NEXT: movw r24, r22 |
| ; CHECK-NEXT: ret |
| %res = ashr i32 %a, 31 |
| ret i32 %res |
| } |