llvm-project/llvm/test/CodeGen/AArch64/shift-amount-mod.ll
Sander de Smalen 61510b51c3 Revert "[AArch64] Enable subreg liveness tracking by default."
This reverts commit 9c319d5bb40785c969d2af76535ca62448dfafa7.

Some issues were discovered with the bootstrap builds, which
seem like they were caused by this commit. I'm reverting to investigate.
2024-12-12 17:22:15 +00:00

1204 lines
38 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=aarch64-unknown-unknown | FileCheck %s
;==============================================================================;
; the shift amount is negated (shiftbitwidth - shiftamt)
;==============================================================================;
; shift left
;------------------------------------------------------------------------------;
define i32 @reg32_shl_by_negated(i32 %val, i32 %shamt) nounwind {
; CHECK-LABEL: reg32_shl_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: neg w8, w1
; CHECK-NEXT: lsl w0, w0, w8
; CHECK-NEXT: ret
%negshamt = sub i32 32, %shamt
%shifted = shl i32 %val, %negshamt
ret i32 %shifted
}
define i32 @load32_shl_by_negated(ptr %valptr, i32 %shamt) nounwind {
; CHECK-LABEL: load32_shl_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: neg w9, w1
; CHECK-NEXT: lsl w0, w8, w9
; CHECK-NEXT: ret
%val = load i32, ptr %valptr
%negshamt = sub i32 32, %shamt
%shifted = shl i32 %val, %negshamt
ret i32 %shifted
}
define void @store32_shl_by_negated(i32 %val, ptr %dstptr, i32 %shamt) nounwind {
; CHECK-LABEL: store32_shl_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: neg w8, w2
; CHECK-NEXT: lsl w8, w0, w8
; CHECK-NEXT: str w8, [x1]
; CHECK-NEXT: ret
%negshamt = sub i32 32, %shamt
%shifted = shl i32 %val, %negshamt
store i32 %shifted, ptr %dstptr
ret void
}
define void @modify32_shl_by_negated(ptr %valptr, i32 %shamt) nounwind {
; CHECK-LABEL: modify32_shl_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: neg w9, w1
; CHECK-NEXT: lsl w8, w8, w9
; CHECK-NEXT: str w8, [x0]
; CHECK-NEXT: ret
%val = load i32, ptr %valptr
%negshamt = sub i32 32, %shamt
%shifted = shl i32 %val, %negshamt
store i32 %shifted, ptr %valptr
ret void
}
define void @modify32_shl_by_negated_multi_use(ptr %valptr, i32 %shamt, ptr %shamtptr) nounwind {
; CHECK-LABEL: modify32_shl_by_negated_multi_use:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: neg w9, w1
; CHECK-NEXT: lsl w8, w8, w9
; CHECK-NEXT: mov w9, #32 // =0x20
; CHECK-NEXT: sub w9, w9, w1
; CHECK-NEXT: str w8, [x0]
; CHECK-NEXT: str w9, [x2]
; CHECK-NEXT: ret
%val = load i32, ptr %valptr
%negshamt = sub i32 32, %shamt
%shifted = shl i32 %val, %negshamt
store i32 %shifted, ptr %valptr
store i32 %negshamt, ptr %shamtptr
ret void
}
define i64 @reg64_shl_by_negated(i64 %val, i64 %shamt) nounwind {
; CHECK-LABEL: reg64_shl_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: neg x8, x1
; CHECK-NEXT: lsl x0, x0, x8
; CHECK-NEXT: ret
%negshamt = sub i64 64, %shamt
%shifted = shl i64 %val, %negshamt
ret i64 %shifted
}
define i64 @load64_shl_by_negated(ptr %valptr, i64 %shamt) nounwind {
; CHECK-LABEL: load64_shl_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr x8, [x0]
; CHECK-NEXT: neg x9, x1
; CHECK-NEXT: lsl x0, x8, x9
; CHECK-NEXT: ret
%val = load i64, ptr %valptr
%negshamt = sub i64 64, %shamt
%shifted = shl i64 %val, %negshamt
ret i64 %shifted
}
define void @store64_shl_by_negated(i64 %val, ptr %dstptr, i64 %shamt) nounwind {
; CHECK-LABEL: store64_shl_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: neg x8, x2
; CHECK-NEXT: lsl x8, x0, x8
; CHECK-NEXT: str x8, [x1]
; CHECK-NEXT: ret
%negshamt = sub i64 64, %shamt
%shifted = shl i64 %val, %negshamt
store i64 %shifted, ptr %dstptr
ret void
}
define void @modify64_shl_by_negated(ptr %valptr, i64 %shamt) nounwind {
; CHECK-LABEL: modify64_shl_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr x8, [x0]
; CHECK-NEXT: neg x9, x1
; CHECK-NEXT: lsl x8, x8, x9
; CHECK-NEXT: str x8, [x0]
; CHECK-NEXT: ret
%val = load i64, ptr %valptr
%negshamt = sub i64 64, %shamt
%shifted = shl i64 %val, %negshamt
store i64 %shifted, ptr %valptr
ret void
}
define void @modify64_shl_by_negated_multi_use(ptr %valptr, i64 %shamt, ptr %shamtptr) nounwind {
; CHECK-LABEL: modify64_shl_by_negated_multi_use:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr x8, [x0]
; CHECK-NEXT: neg x9, x1
; CHECK-NEXT: lsl x8, x8, x9
; CHECK-NEXT: mov w9, #64 // =0x40
; CHECK-NEXT: sub x9, x9, x1
; CHECK-NEXT: str x8, [x0]
; CHECK-NEXT: str x9, [x2]
; CHECK-NEXT: ret
%val = load i64, ptr %valptr
%negshamt = sub i64 64, %shamt
%shifted = shl i64 %val, %negshamt
store i64 %shifted, ptr %valptr
store i64 %negshamt, ptr %shamtptr
ret void
}
; logical shift right
;------------------------------------------------------------------------------;
define i32 @reg32_lshr_by_negated(i32 %val, i32 %shamt) nounwind {
; CHECK-LABEL: reg32_lshr_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: neg w8, w1
; CHECK-NEXT: lsr w0, w0, w8
; CHECK-NEXT: ret
%negshamt = sub i32 32, %shamt
%shifted = lshr i32 %val, %negshamt
ret i32 %shifted
}
define i32 @load32_lshr_by_negated(ptr %valptr, i32 %shamt) nounwind {
; CHECK-LABEL: load32_lshr_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: neg w9, w1
; CHECK-NEXT: lsr w0, w8, w9
; CHECK-NEXT: ret
%val = load i32, ptr %valptr
%negshamt = sub i32 32, %shamt
%shifted = lshr i32 %val, %negshamt
ret i32 %shifted
}
define void @store32_lshr_by_negated(i32 %val, ptr %dstptr, i32 %shamt) nounwind {
; CHECK-LABEL: store32_lshr_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: neg w8, w2
; CHECK-NEXT: lsr w8, w0, w8
; CHECK-NEXT: str w8, [x1]
; CHECK-NEXT: ret
%negshamt = sub i32 32, %shamt
%shifted = lshr i32 %val, %negshamt
store i32 %shifted, ptr %dstptr
ret void
}
define void @modify32_lshr_by_negated(ptr %valptr, i32 %shamt) nounwind {
; CHECK-LABEL: modify32_lshr_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: neg w9, w1
; CHECK-NEXT: lsr w8, w8, w9
; CHECK-NEXT: str w8, [x0]
; CHECK-NEXT: ret
%val = load i32, ptr %valptr
%negshamt = sub i32 32, %shamt
%shifted = lshr i32 %val, %negshamt
store i32 %shifted, ptr %valptr
ret void
}
define void @modify32_lshr_by_negated_multi_use(ptr %valptr, i32 %shamt, ptr %shamtptr) nounwind {
; CHECK-LABEL: modify32_lshr_by_negated_multi_use:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: neg w9, w1
; CHECK-NEXT: lsr w8, w8, w9
; CHECK-NEXT: mov w9, #32 // =0x20
; CHECK-NEXT: sub w9, w9, w1
; CHECK-NEXT: str w8, [x0]
; CHECK-NEXT: str w9, [x2]
; CHECK-NEXT: ret
%val = load i32, ptr %valptr
%negshamt = sub i32 32, %shamt
%shifted = lshr i32 %val, %negshamt
store i32 %shifted, ptr %valptr
store i32 %negshamt, ptr %shamtptr
ret void
}
define i64 @reg64_lshr_by_negated(i64 %val, i64 %shamt) nounwind {
; CHECK-LABEL: reg64_lshr_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: neg x8, x1
; CHECK-NEXT: lsr x0, x0, x8
; CHECK-NEXT: ret
%negshamt = sub i64 64, %shamt
%shifted = lshr i64 %val, %negshamt
ret i64 %shifted
}
define i64 @load64_lshr_by_negated(ptr %valptr, i64 %shamt) nounwind {
; CHECK-LABEL: load64_lshr_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr x8, [x0]
; CHECK-NEXT: neg x9, x1
; CHECK-NEXT: lsr x0, x8, x9
; CHECK-NEXT: ret
%val = load i64, ptr %valptr
%negshamt = sub i64 64, %shamt
%shifted = lshr i64 %val, %negshamt
ret i64 %shifted
}
define void @store64_lshr_by_negated(i64 %val, ptr %dstptr, i64 %shamt) nounwind {
; CHECK-LABEL: store64_lshr_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: neg x8, x2
; CHECK-NEXT: lsr x8, x0, x8
; CHECK-NEXT: str x8, [x1]
; CHECK-NEXT: ret
%negshamt = sub i64 64, %shamt
%shifted = lshr i64 %val, %negshamt
store i64 %shifted, ptr %dstptr
ret void
}
define void @modify64_lshr_by_negated(ptr %valptr, i64 %shamt) nounwind {
; CHECK-LABEL: modify64_lshr_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr x8, [x0]
; CHECK-NEXT: neg x9, x1
; CHECK-NEXT: lsr x8, x8, x9
; CHECK-NEXT: str x8, [x0]
; CHECK-NEXT: ret
%val = load i64, ptr %valptr
%negshamt = sub i64 64, %shamt
%shifted = lshr i64 %val, %negshamt
store i64 %shifted, ptr %valptr
ret void
}
define void @modify64_lshr_by_negated_multi_use(ptr %valptr, i64 %shamt, ptr %shamtptr) nounwind {
; CHECK-LABEL: modify64_lshr_by_negated_multi_use:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr x8, [x0]
; CHECK-NEXT: neg x9, x1
; CHECK-NEXT: lsr x8, x8, x9
; CHECK-NEXT: mov w9, #64 // =0x40
; CHECK-NEXT: sub x9, x9, x1
; CHECK-NEXT: str x8, [x0]
; CHECK-NEXT: str x9, [x2]
; CHECK-NEXT: ret
%val = load i64, ptr %valptr
%negshamt = sub i64 64, %shamt
%shifted = lshr i64 %val, %negshamt
store i64 %shifted, ptr %valptr
store i64 %negshamt, ptr %shamtptr
ret void
}
; arithmetic shift right
;------------------------------------------------------------------------------;
define i32 @reg32_ashr_by_negated(i32 %val, i32 %shamt) nounwind {
; CHECK-LABEL: reg32_ashr_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: neg w8, w1
; CHECK-NEXT: asr w0, w0, w8
; CHECK-NEXT: ret
%negshamt = sub i32 32, %shamt
%shifted = ashr i32 %val, %negshamt
ret i32 %shifted
}
define i32 @load32_ashr_by_negated(ptr %valptr, i32 %shamt) nounwind {
; CHECK-LABEL: load32_ashr_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: neg w9, w1
; CHECK-NEXT: asr w0, w8, w9
; CHECK-NEXT: ret
%val = load i32, ptr %valptr
%negshamt = sub i32 32, %shamt
%shifted = ashr i32 %val, %negshamt
ret i32 %shifted
}
define void @store32_ashr_by_negated(i32 %val, ptr %dstptr, i32 %shamt) nounwind {
; CHECK-LABEL: store32_ashr_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: neg w8, w2
; CHECK-NEXT: asr w8, w0, w8
; CHECK-NEXT: str w8, [x1]
; CHECK-NEXT: ret
%negshamt = sub i32 32, %shamt
%shifted = ashr i32 %val, %negshamt
store i32 %shifted, ptr %dstptr
ret void
}
define void @modify32_ashr_by_negated(ptr %valptr, i32 %shamt) nounwind {
; CHECK-LABEL: modify32_ashr_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: neg w9, w1
; CHECK-NEXT: asr w8, w8, w9
; CHECK-NEXT: str w8, [x0]
; CHECK-NEXT: ret
%val = load i32, ptr %valptr
%negshamt = sub i32 32, %shamt
%shifted = ashr i32 %val, %negshamt
store i32 %shifted, ptr %valptr
ret void
}
define void @modify32_ashr_by_negated_multi_use(ptr %valptr, i32 %shamt, ptr %shamtptr) nounwind {
; CHECK-LABEL: modify32_ashr_by_negated_multi_use:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: neg w9, w1
; CHECK-NEXT: asr w8, w8, w9
; CHECK-NEXT: mov w9, #32 // =0x20
; CHECK-NEXT: sub w9, w9, w1
; CHECK-NEXT: str w8, [x0]
; CHECK-NEXT: str w9, [x2]
; CHECK-NEXT: ret
%val = load i32, ptr %valptr
%negshamt = sub i32 32, %shamt
%shifted = ashr i32 %val, %negshamt
store i32 %shifted, ptr %valptr
store i32 %negshamt, ptr %shamtptr
ret void
}
define i64 @reg64_ashr_by_negated(i64 %val, i64 %shamt) nounwind {
; CHECK-LABEL: reg64_ashr_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: neg x8, x1
; CHECK-NEXT: asr x0, x0, x8
; CHECK-NEXT: ret
%negshamt = sub i64 64, %shamt
%shifted = ashr i64 %val, %negshamt
ret i64 %shifted
}
define i64 @load64_ashr_by_negated(ptr %valptr, i64 %shamt) nounwind {
; CHECK-LABEL: load64_ashr_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr x8, [x0]
; CHECK-NEXT: neg x9, x1
; CHECK-NEXT: asr x0, x8, x9
; CHECK-NEXT: ret
%val = load i64, ptr %valptr
%negshamt = sub i64 64, %shamt
%shifted = ashr i64 %val, %negshamt
ret i64 %shifted
}
define void @store64_ashr_by_negated(i64 %val, ptr %dstptr, i64 %shamt) nounwind {
; CHECK-LABEL: store64_ashr_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: neg x8, x2
; CHECK-NEXT: asr x8, x0, x8
; CHECK-NEXT: str x8, [x1]
; CHECK-NEXT: ret
%negshamt = sub i64 64, %shamt
%shifted = ashr i64 %val, %negshamt
store i64 %shifted, ptr %dstptr
ret void
}
define void @modify64_ashr_by_negated(ptr %valptr, i64 %shamt) nounwind {
; CHECK-LABEL: modify64_ashr_by_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr x8, [x0]
; CHECK-NEXT: neg x9, x1
; CHECK-NEXT: asr x8, x8, x9
; CHECK-NEXT: str x8, [x0]
; CHECK-NEXT: ret
%val = load i64, ptr %valptr
%negshamt = sub i64 64, %shamt
%shifted = ashr i64 %val, %negshamt
store i64 %shifted, ptr %valptr
ret void
}
define void @modify64_ashr_by_negated_multi_use(ptr %valptr, i64 %shamt, ptr %shamtptr) nounwind {
; CHECK-LABEL: modify64_ashr_by_negated_multi_use:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr x8, [x0]
; CHECK-NEXT: neg x9, x1
; CHECK-NEXT: asr x8, x8, x9
; CHECK-NEXT: mov w9, #64 // =0x40
; CHECK-NEXT: sub x9, x9, x1
; CHECK-NEXT: str x8, [x0]
; CHECK-NEXT: str x9, [x2]
; CHECK-NEXT: ret
%val = load i64, ptr %valptr
%negshamt = sub i64 64, %shamt
%shifted = ashr i64 %val, %negshamt
store i64 %shifted, ptr %valptr
store i64 %negshamt, ptr %shamtptr
ret void
}
;==============================================================================;
; the shift amount is complemented (shiftbitwidth - 1 - shiftamt)
;==============================================================================;
; shift left
;------------------------------------------------------------------------------;
define i32 @reg32_shl_by_complemented(i32 %val, i32 %shamt) nounwind {
; CHECK-LABEL: reg32_shl_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: mvn w8, w1
; CHECK-NEXT: lsl w0, w0, w8
; CHECK-NEXT: ret
%negshamt = sub i32 31, %shamt
%shifted = shl i32 %val, %negshamt
ret i32 %shifted
}
define i32 @load32_shl_by_complemented(ptr %valptr, i32 %shamt) nounwind {
; CHECK-LABEL: load32_shl_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: mvn w9, w1
; CHECK-NEXT: lsl w0, w8, w9
; CHECK-NEXT: ret
%val = load i32, ptr %valptr
%negshamt = sub i32 31, %shamt
%shifted = shl i32 %val, %negshamt
ret i32 %shifted
}
define void @store32_shl_by_complemented(i32 %val, ptr %dstptr, i32 %shamt) nounwind {
; CHECK-LABEL: store32_shl_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: mvn w8, w2
; CHECK-NEXT: lsl w8, w0, w8
; CHECK-NEXT: str w8, [x1]
; CHECK-NEXT: ret
%negshamt = sub i32 31, %shamt
%shifted = shl i32 %val, %negshamt
store i32 %shifted, ptr %dstptr
ret void
}
define void @modify32_shl_by_complemented(ptr %valptr, i32 %shamt) nounwind {
; CHECK-LABEL: modify32_shl_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: mvn w9, w1
; CHECK-NEXT: lsl w8, w8, w9
; CHECK-NEXT: str w8, [x0]
; CHECK-NEXT: ret
%val = load i32, ptr %valptr
%negshamt = sub i32 31, %shamt
%shifted = shl i32 %val, %negshamt
store i32 %shifted, ptr %valptr
ret void
}
define void @modify32_shl_by_complemented_multi_use(ptr %valptr, i32 %shamt, ptr %shamtptr) nounwind {
; CHECK-LABEL: modify32_shl_by_complemented_multi_use:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: mvn w9, w1
; CHECK-NEXT: lsl w8, w8, w9
; CHECK-NEXT: mov w9, #31 // =0x1f
; CHECK-NEXT: sub w9, w9, w1
; CHECK-NEXT: str w8, [x0]
; CHECK-NEXT: str w9, [x2]
; CHECK-NEXT: ret
%val = load i32, ptr %valptr
%negshamt = sub i32 31, %shamt
%shifted = shl i32 %val, %negshamt
store i32 %shifted, ptr %valptr
store i32 %negshamt, ptr %shamtptr
ret void
}
define i64 @reg64_shl_by_complemented(i64 %val, i64 %shamt) nounwind {
; CHECK-LABEL: reg64_shl_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: mvn x8, x1
; CHECK-NEXT: lsl x0, x0, x8
; CHECK-NEXT: ret
%negshamt = sub i64 63, %shamt
%shifted = shl i64 %val, %negshamt
ret i64 %shifted
}
define i64 @load64_shl_by_complemented(ptr %valptr, i64 %shamt) nounwind {
; CHECK-LABEL: load64_shl_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr x8, [x0]
; CHECK-NEXT: mvn x9, x1
; CHECK-NEXT: lsl x0, x8, x9
; CHECK-NEXT: ret
%val = load i64, ptr %valptr
%negshamt = sub i64 63, %shamt
%shifted = shl i64 %val, %negshamt
ret i64 %shifted
}
define void @store64_shl_by_complemented(i64 %val, ptr %dstptr, i64 %shamt) nounwind {
; CHECK-LABEL: store64_shl_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: mvn x8, x2
; CHECK-NEXT: lsl x8, x0, x8
; CHECK-NEXT: str x8, [x1]
; CHECK-NEXT: ret
%negshamt = sub i64 63, %shamt
%shifted = shl i64 %val, %negshamt
store i64 %shifted, ptr %dstptr
ret void
}
define void @modify64_shl_by_complemented(ptr %valptr, i64 %shamt) nounwind {
; CHECK-LABEL: modify64_shl_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr x8, [x0]
; CHECK-NEXT: mvn x9, x1
; CHECK-NEXT: lsl x8, x8, x9
; CHECK-NEXT: str x8, [x0]
; CHECK-NEXT: ret
%val = load i64, ptr %valptr
%negshamt = sub i64 63, %shamt
%shifted = shl i64 %val, %negshamt
store i64 %shifted, ptr %valptr
ret void
}
define void @modify64_shl_by_complemented_multi_use(ptr %valptr, i64 %shamt, ptr %shamtptr) nounwind {
; CHECK-LABEL: modify64_shl_by_complemented_multi_use:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr x8, [x0]
; CHECK-NEXT: mvn x9, x1
; CHECK-NEXT: lsl x8, x8, x9
; CHECK-NEXT: mov w9, #63 // =0x3f
; CHECK-NEXT: sub x9, x9, x1
; CHECK-NEXT: str x8, [x0]
; CHECK-NEXT: str x9, [x2]
; CHECK-NEXT: ret
%val = load i64, ptr %valptr
%negshamt = sub i64 63, %shamt
%shifted = shl i64 %val, %negshamt
store i64 %shifted, ptr %valptr
store i64 %negshamt, ptr %shamtptr
ret void
}
; logical shift right
;------------------------------------------------------------------------------;
define i32 @reg32_lshr_by_complemented(i32 %val, i32 %shamt) nounwind {
; CHECK-LABEL: reg32_lshr_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: mvn w8, w1
; CHECK-NEXT: lsr w0, w0, w8
; CHECK-NEXT: ret
%negshamt = sub i32 31, %shamt
%shifted = lshr i32 %val, %negshamt
ret i32 %shifted
}
define i32 @load32_lshr_by_complemented(ptr %valptr, i32 %shamt) nounwind {
; CHECK-LABEL: load32_lshr_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: mvn w9, w1
; CHECK-NEXT: lsr w0, w8, w9
; CHECK-NEXT: ret
%val = load i32, ptr %valptr
%negshamt = sub i32 31, %shamt
%shifted = lshr i32 %val, %negshamt
ret i32 %shifted
}
define void @store32_lshr_by_complemented(i32 %val, ptr %dstptr, i32 %shamt) nounwind {
; CHECK-LABEL: store32_lshr_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: mvn w8, w2
; CHECK-NEXT: lsr w8, w0, w8
; CHECK-NEXT: str w8, [x1]
; CHECK-NEXT: ret
%negshamt = sub i32 31, %shamt
%shifted = lshr i32 %val, %negshamt
store i32 %shifted, ptr %dstptr
ret void
}
define void @modify32_lshr_by_complemented(ptr %valptr, i32 %shamt) nounwind {
; CHECK-LABEL: modify32_lshr_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: mvn w9, w1
; CHECK-NEXT: lsr w8, w8, w9
; CHECK-NEXT: str w8, [x0]
; CHECK-NEXT: ret
%val = load i32, ptr %valptr
%negshamt = sub i32 31, %shamt
%shifted = lshr i32 %val, %negshamt
store i32 %shifted, ptr %valptr
ret void
}
define void @modify32_lshr_by_complemented_multi_use(ptr %valptr, i32 %shamt, ptr %shamtptr) nounwind {
; CHECK-LABEL: modify32_lshr_by_complemented_multi_use:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: mvn w9, w1
; CHECK-NEXT: lsr w8, w8, w9
; CHECK-NEXT: mov w9, #31 // =0x1f
; CHECK-NEXT: sub w9, w9, w1
; CHECK-NEXT: str w8, [x0]
; CHECK-NEXT: str w9, [x2]
; CHECK-NEXT: ret
%val = load i32, ptr %valptr
%negshamt = sub i32 31, %shamt
%shifted = lshr i32 %val, %negshamt
store i32 %shifted, ptr %valptr
store i32 %negshamt, ptr %shamtptr
ret void
}
define i64 @reg64_lshr_by_complemented(i64 %val, i64 %shamt) nounwind {
; CHECK-LABEL: reg64_lshr_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: mvn x8, x1
; CHECK-NEXT: lsr x0, x0, x8
; CHECK-NEXT: ret
%negshamt = sub i64 63, %shamt
%shifted = lshr i64 %val, %negshamt
ret i64 %shifted
}
define i64 @load64_lshr_by_complemented(ptr %valptr, i64 %shamt) nounwind {
; CHECK-LABEL: load64_lshr_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr x8, [x0]
; CHECK-NEXT: mvn x9, x1
; CHECK-NEXT: lsr x0, x8, x9
; CHECK-NEXT: ret
%val = load i64, ptr %valptr
%negshamt = sub i64 63, %shamt
%shifted = lshr i64 %val, %negshamt
ret i64 %shifted
}
define void @store64_lshr_by_complemented(i64 %val, ptr %dstptr, i64 %shamt) nounwind {
; CHECK-LABEL: store64_lshr_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: mvn x8, x2
; CHECK-NEXT: lsr x8, x0, x8
; CHECK-NEXT: str x8, [x1]
; CHECK-NEXT: ret
%negshamt = sub i64 63, %shamt
%shifted = lshr i64 %val, %negshamt
store i64 %shifted, ptr %dstptr
ret void
}
define void @modify64_lshr_by_complemented(ptr %valptr, i64 %shamt) nounwind {
; CHECK-LABEL: modify64_lshr_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr x8, [x0]
; CHECK-NEXT: mvn x9, x1
; CHECK-NEXT: lsr x8, x8, x9
; CHECK-NEXT: str x8, [x0]
; CHECK-NEXT: ret
%val = load i64, ptr %valptr
%negshamt = sub i64 63, %shamt
%shifted = lshr i64 %val, %negshamt
store i64 %shifted, ptr %valptr
ret void
}
define void @modify64_lshr_by_complemented_multi_use(ptr %valptr, i64 %shamt, ptr %shamtptr) nounwind {
; CHECK-LABEL: modify64_lshr_by_complemented_multi_use:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr x8, [x0]
; CHECK-NEXT: mvn x9, x1
; CHECK-NEXT: lsr x8, x8, x9
; CHECK-NEXT: mov w9, #63 // =0x3f
; CHECK-NEXT: sub x9, x9, x1
; CHECK-NEXT: str x8, [x0]
; CHECK-NEXT: str x9, [x2]
; CHECK-NEXT: ret
%val = load i64, ptr %valptr
%negshamt = sub i64 63, %shamt
%shifted = lshr i64 %val, %negshamt
store i64 %shifted, ptr %valptr
store i64 %negshamt, ptr %shamtptr
ret void
}
; arithmetic shift right
;------------------------------------------------------------------------------;
define i32 @reg32_ashr_by_complemented(i32 %val, i32 %shamt) nounwind {
; CHECK-LABEL: reg32_ashr_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: mvn w8, w1
; CHECK-NEXT: asr w0, w0, w8
; CHECK-NEXT: ret
%negshamt = sub i32 31, %shamt
%shifted = ashr i32 %val, %negshamt
ret i32 %shifted
}
define i32 @load32_ashr_by_complemented(ptr %valptr, i32 %shamt) nounwind {
; CHECK-LABEL: load32_ashr_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: mvn w9, w1
; CHECK-NEXT: asr w0, w8, w9
; CHECK-NEXT: ret
%val = load i32, ptr %valptr
%negshamt = sub i32 31, %shamt
%shifted = ashr i32 %val, %negshamt
ret i32 %shifted
}
define void @store32_ashr_by_complemented(i32 %val, ptr %dstptr, i32 %shamt) nounwind {
; CHECK-LABEL: store32_ashr_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: mvn w8, w2
; CHECK-NEXT: asr w8, w0, w8
; CHECK-NEXT: str w8, [x1]
; CHECK-NEXT: ret
%negshamt = sub i32 31, %shamt
%shifted = ashr i32 %val, %negshamt
store i32 %shifted, ptr %dstptr
ret void
}
define void @modify32_ashr_by_complemented(ptr %valptr, i32 %shamt) nounwind {
; CHECK-LABEL: modify32_ashr_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: mvn w9, w1
; CHECK-NEXT: asr w8, w8, w9
; CHECK-NEXT: str w8, [x0]
; CHECK-NEXT: ret
%val = load i32, ptr %valptr
%negshamt = sub i32 31, %shamt
%shifted = ashr i32 %val, %negshamt
store i32 %shifted, ptr %valptr
ret void
}
define void @modify32_ashr_by_complemented_multi_use(ptr %valptr, i32 %shamt, ptr %shamtptr) nounwind {
; CHECK-LABEL: modify32_ashr_by_complemented_multi_use:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: mvn w9, w1
; CHECK-NEXT: asr w8, w8, w9
; CHECK-NEXT: mov w9, #31 // =0x1f
; CHECK-NEXT: sub w9, w9, w1
; CHECK-NEXT: str w8, [x0]
; CHECK-NEXT: str w9, [x2]
; CHECK-NEXT: ret
%val = load i32, ptr %valptr
%negshamt = sub i32 31, %shamt
%shifted = ashr i32 %val, %negshamt
store i32 %shifted, ptr %valptr
store i32 %negshamt, ptr %shamtptr
ret void
}
define i64 @reg64_ashr_by_complemented(i64 %val, i64 %shamt) nounwind {
; CHECK-LABEL: reg64_ashr_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: mvn x8, x1
; CHECK-NEXT: asr x0, x0, x8
; CHECK-NEXT: ret
%negshamt = sub i64 63, %shamt
%shifted = ashr i64 %val, %negshamt
ret i64 %shifted
}
define i64 @load64_ashr_by_complemented(ptr %valptr, i64 %shamt) nounwind {
; CHECK-LABEL: load64_ashr_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr x8, [x0]
; CHECK-NEXT: mvn x9, x1
; CHECK-NEXT: asr x0, x8, x9
; CHECK-NEXT: ret
%val = load i64, ptr %valptr
%negshamt = sub i64 63, %shamt
%shifted = ashr i64 %val, %negshamt
ret i64 %shifted
}
define void @store64_ashr_by_complemented(i64 %val, ptr %dstptr, i64 %shamt) nounwind {
; CHECK-LABEL: store64_ashr_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: mvn x8, x2
; CHECK-NEXT: asr x8, x0, x8
; CHECK-NEXT: str x8, [x1]
; CHECK-NEXT: ret
%negshamt = sub i64 63, %shamt
%shifted = ashr i64 %val, %negshamt
store i64 %shifted, ptr %dstptr
ret void
}
define void @modify64_ashr_by_complemented(ptr %valptr, i64 %shamt) nounwind {
; CHECK-LABEL: modify64_ashr_by_complemented:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr x8, [x0]
; CHECK-NEXT: mvn x9, x1
; CHECK-NEXT: asr x8, x8, x9
; CHECK-NEXT: str x8, [x0]
; CHECK-NEXT: ret
%val = load i64, ptr %valptr
%negshamt = sub i64 63, %shamt
%shifted = ashr i64 %val, %negshamt
store i64 %shifted, ptr %valptr
ret void
}
define void @modify64_ashr_by_complemented_multi_use(ptr %valptr, i64 %shamt, ptr %shamtptr) nounwind {
; CHECK-LABEL: modify64_ashr_by_complemented_multi_use:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr x8, [x0]
; CHECK-NEXT: mvn x9, x1
; CHECK-NEXT: asr x8, x8, x9
; CHECK-NEXT: mov w9, #63 // =0x3f
; CHECK-NEXT: sub x9, x9, x1
; CHECK-NEXT: str x8, [x0]
; CHECK-NEXT: str x9, [x2]
; CHECK-NEXT: ret
%val = load i64, ptr %valptr
%negshamt = sub i64 63, %shamt
%shifted = ashr i64 %val, %negshamt
store i64 %shifted, ptr %valptr
store i64 %negshamt, ptr %shamtptr
ret void
}
;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||;
; next let's only test simple reg pattern, and only lshr.
;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||;
;==============================================================================;
; subtraction from negated shift amount
define i32 @reg32_lshr_by_sub_from_negated(i32 %val, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: reg32_lshr_by_sub_from_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: add w8, w1, w2
; CHECK-NEXT: neg w8, w8
; CHECK-NEXT: lsr w0, w0, w8
; CHECK-NEXT: ret
%nega = sub i32 32, %a
%negasubb = sub i32 %nega, %b
%shifted = lshr i32 %val, %negasubb
ret i32 %shifted
}
define i64 @reg64_lshr_by_sub_from_negated(i64 %val, i64 %a, i64 %b) nounwind {
; CHECK-LABEL: reg64_lshr_by_sub_from_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: add x8, x1, x2
; CHECK-NEXT: neg x8, x8
; CHECK-NEXT: lsr x0, x0, x8
; CHECK-NEXT: ret
%nega = sub i64 64, %a
%negasubb = sub i64 %nega, %b
%shifted = lshr i64 %val, %negasubb
ret i64 %shifted
}
;==============================================================================;
; subtraction of negated shift amount
define i32 @reg32_lshr_by_sub_of_negated(i32 %val, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: reg32_lshr_by_sub_of_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: add w8, w1, w2
; CHECK-NEXT: lsr w0, w0, w8
; CHECK-NEXT: ret
%nega = sub i32 32, %a
%negasubb = sub i32 %b, %nega
%shifted = lshr i32 %val, %negasubb
ret i32 %shifted
}
define i64 @reg64_lshr_by_sub_of_negated(i64 %val, i64 %a, i64 %b) nounwind {
; CHECK-LABEL: reg64_lshr_by_sub_of_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: add x8, x1, x2
; CHECK-NEXT: lsr x0, x0, x8
; CHECK-NEXT: ret
%nega = sub i64 64, %a
%negasubb = sub i64 %b, %nega
%shifted = lshr i64 %val, %negasubb
ret i64 %shifted
}
;==============================================================================;
; add to negated shift amount
;
define i32 @reg32_lshr_by_add_to_negated(i32 %val, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: reg32_lshr_by_add_to_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: sub w8, w2, w1
; CHECK-NEXT: lsr w0, w0, w8
; CHECK-NEXT: ret
%nega = sub i32 32, %a
%negasubb = add i32 %nega, %b
%shifted = lshr i32 %val, %negasubb
ret i32 %shifted
}
define i64 @reg64_lshr_by_add_to_negated(i64 %val, i64 %a, i64 %b) nounwind {
; CHECK-LABEL: reg64_lshr_by_add_to_negated:
; CHECK: // %bb.0:
; CHECK-NEXT: sub x8, x2, x1
; CHECK-NEXT: lsr x0, x0, x8
; CHECK-NEXT: ret
%nega = sub i64 64, %a
%negasubb = add i64 %nega, %b
%shifted = lshr i64 %val, %negasubb
ret i64 %shifted
}
;==============================================================================;
; subtraction of negated shift amounts
define i32 @reg32_lshr_by_sub_of_negated_amts(i32 %val, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: reg32_lshr_by_sub_of_negated_amts:
; CHECK: // %bb.0:
; CHECK-NEXT: sub w8, w2, w1
; CHECK-NEXT: lsr w0, w0, w8
; CHECK-NEXT: ret
%nega = sub i32 32, %a
%negb = sub i32 32, %b
%negasubnegb = sub i32 %nega, %negb
%shifted = lshr i32 %val, %negasubnegb
ret i32 %shifted
}
define i64 @reg64_lshr_by_sub_of_negated_amts(i64 %val, i64 %a, i64 %b) nounwind {
; CHECK-LABEL: reg64_lshr_by_sub_of_negated_amts:
; CHECK: // %bb.0:
; CHECK-NEXT: sub x8, x2, x1
; CHECK-NEXT: lsr x0, x0, x8
; CHECK-NEXT: ret
%nega = sub i64 64, %a
%negb = sub i64 64, %b
%negasubnegb = sub i64 %nega, %negb
%shifted = lshr i64 %val, %negasubnegb
ret i64 %shifted
}
;==============================================================================;
; addition of negated shift amounts
define i32 @reg32_lshr_by_add_of_negated_amts(i32 %val, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: reg32_lshr_by_add_of_negated_amts:
; CHECK: // %bb.0:
; CHECK-NEXT: add w8, w1, w2
; CHECK-NEXT: neg w8, w8
; CHECK-NEXT: lsr w0, w0, w8
; CHECK-NEXT: ret
%nega = sub i32 32, %a
%negb = sub i32 32, %b
%negasubnegb = add i32 %nega, %negb
%shifted = lshr i32 %val, %negasubnegb
ret i32 %shifted
}
define i64 @reg64_lshr_by_add_of_negated_amts(i64 %val, i64 %a, i64 %b) nounwind {
; CHECK-LABEL: reg64_lshr_by_add_of_negated_amts:
; CHECK: // %bb.0:
; CHECK-NEXT: add x8, x1, x2
; CHECK-NEXT: neg x8, x8
; CHECK-NEXT: lsr x0, x0, x8
; CHECK-NEXT: ret
%nega = sub i64 64, %a
%negb = sub i64 64, %b
%negasubnegb = add i64 %nega, %negb
%shifted = lshr i64 %val, %negasubnegb
ret i64 %shifted
}
;==============================================================================;
; and patterns with an actual negation+addition
define i32 @reg32_lshr_by_negated_unfolded(i32 %val, i32 %shamt) nounwind {
; CHECK-LABEL: reg32_lshr_by_negated_unfolded:
; CHECK: // %bb.0:
; CHECK-NEXT: neg w8, w1
; CHECK-NEXT: lsr w0, w0, w8
; CHECK-NEXT: ret
%negshamt = sub i32 0, %shamt
%negaaddbitwidth = add i32 %negshamt, 32
%shifted = lshr i32 %val, %negaaddbitwidth
ret i32 %shifted
}
define i64 @reg64_lshr_by_negated_unfolded(i64 %val, i64 %shamt) nounwind {
; CHECK-LABEL: reg64_lshr_by_negated_unfolded:
; CHECK: // %bb.0:
; CHECK-NEXT: neg x8, x1
; CHECK-NEXT: lsr x0, x0, x8
; CHECK-NEXT: ret
%negshamt = sub i64 0, %shamt
%negaaddbitwidth = add i64 %negshamt, 64
%shifted = lshr i64 %val, %negaaddbitwidth
ret i64 %shifted
}
define i32 @reg32_lshr_by_negated_unfolded_sub_b(i32 %val, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: reg32_lshr_by_negated_unfolded_sub_b:
; CHECK: // %bb.0:
; CHECK-NEXT: add w8, w1, w2
; CHECK-NEXT: neg w8, w8
; CHECK-NEXT: lsr w0, w0, w8
; CHECK-NEXT: ret
%nega = sub i32 0, %a
%negaaddbitwidth = add i32 %nega, 32
%negaaddbitwidthsubb = sub i32 %negaaddbitwidth, %b
%shifted = lshr i32 %val, %negaaddbitwidthsubb
ret i32 %shifted
}
define i64 @reg64_lshr_by_negated_unfolded_sub_b(i64 %val, i64 %a, i64 %b) nounwind {
; CHECK-LABEL: reg64_lshr_by_negated_unfolded_sub_b:
; CHECK: // %bb.0:
; CHECK-NEXT: add x8, x1, x2
; CHECK-NEXT: neg x8, x8
; CHECK-NEXT: lsr x0, x0, x8
; CHECK-NEXT: ret
%nega = sub i64 0, %a
%negaaddbitwidth = add i64 %nega, 64
%negaaddbitwidthsubb = sub i64 %negaaddbitwidth, %b
%shifted = lshr i64 %val, %negaaddbitwidthsubb
ret i64 %shifted
}
define i32 @reg32_lshr_by_b_sub_negated_unfolded(i32 %val, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: reg32_lshr_by_b_sub_negated_unfolded:
; CHECK: // %bb.0:
; CHECK-NEXT: add w8, w2, w1
; CHECK-NEXT: lsr w0, w0, w8
; CHECK-NEXT: ret
%nega = sub i32 0, %a
%negaaddbitwidth = add i32 %nega, 32
%negaaddbitwidthsubb = sub i32 %b, %negaaddbitwidth
%shifted = lshr i32 %val, %negaaddbitwidthsubb
ret i32 %shifted
}
define i64 @reg64_lshr_by_b_sub_negated_unfolded(i64 %val, i64 %a, i64 %b) nounwind {
; CHECK-LABEL: reg64_lshr_by_b_sub_negated_unfolded:
; CHECK: // %bb.0:
; CHECK-NEXT: add x8, x2, x1
; CHECK-NEXT: lsr x0, x0, x8
; CHECK-NEXT: ret
%nega = sub i64 0, %a
%negaaddbitwidth = add i64 %nega, 64
%negaaddbitwidthsubb = sub i64 %b, %negaaddbitwidth
%shifted = lshr i64 %val, %negaaddbitwidthsubb
ret i64 %shifted
}
define i32 @reg32_lshr_by_negated_unfolded_add_b(i32 %val, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: reg32_lshr_by_negated_unfolded_add_b:
; CHECK: // %bb.0:
; CHECK-NEXT: sub w8, w2, w1
; CHECK-NEXT: lsr w0, w0, w8
; CHECK-NEXT: ret
%nega = sub i32 0, %a
%negaaddbitwidth = add i32 %nega, 32
%negaaddbitwidthaddb = add i32 %negaaddbitwidth, %b
%shifted = lshr i32 %val, %negaaddbitwidthaddb
ret i32 %shifted
}
define i64 @reg64_lshr_by_negated_unfolded_add_b(i64 %val, i64 %a, i64 %b) nounwind {
; CHECK-LABEL: reg64_lshr_by_negated_unfolded_add_b:
; CHECK: // %bb.0:
; CHECK-NEXT: sub x8, x2, x1
; CHECK-NEXT: lsr x0, x0, x8
; CHECK-NEXT: ret
%nega = sub i64 0, %a
%negaaddbitwidth = add i64 %nega, 64
%negaaddbitwidthaddb = add i64 %negaaddbitwidth, %b
%shifted = lshr i64 %val, %negaaddbitwidthaddb
ret i64 %shifted
}
;==============================================================================;
; and patterns with an actual negation+mask
define i32 @reg32_lshr_by_masked_negated_unfolded(i32 %val, i32 %shamt) nounwind {
; CHECK-LABEL: reg32_lshr_by_masked_negated_unfolded:
; CHECK: // %bb.0:
; CHECK-NEXT: neg w8, w1
; CHECK-NEXT: lsr w0, w0, w8
; CHECK-NEXT: ret
%negshamt = sub i32 0, %shamt
%negaaddbitwidth = and i32 %negshamt, 31
%shifted = lshr i32 %val, %negaaddbitwidth
ret i32 %shifted
}
define i64 @reg64_lshr_by_masked_negated_unfolded(i64 %val, i64 %shamt) nounwind {
; CHECK-LABEL: reg64_lshr_by_masked_negated_unfolded:
; CHECK: // %bb.0:
; CHECK-NEXT: neg w8, w1
; CHECK-NEXT: lsr x0, x0, x8
; CHECK-NEXT: ret
%negshamt = sub i64 0, %shamt
%negaaddbitwidth = and i64 %negshamt, 63
%shifted = lshr i64 %val, %negaaddbitwidth
ret i64 %shifted
}
define i32 @reg32_lshr_by_masked_negated_unfolded_sub_b(i32 %val, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: reg32_lshr_by_masked_negated_unfolded_sub_b:
; CHECK: // %bb.0:
; CHECK-NEXT: neg w8, w1
; CHECK-NEXT: and w8, w8, #0x1f
; CHECK-NEXT: sub w8, w8, w2
; CHECK-NEXT: lsr w0, w0, w8
; CHECK-NEXT: ret
%nega = sub i32 0, %a
%negaaddbitwidth = and i32 %nega, 31
%negaaddbitwidthsubb = sub i32 %negaaddbitwidth, %b
%shifted = lshr i32 %val, %negaaddbitwidthsubb
ret i32 %shifted
}
define i64 @reg64_lshr_by_masked_negated_unfolded_sub_b(i64 %val, i64 %a, i64 %b) nounwind {
; CHECK-LABEL: reg64_lshr_by_masked_negated_unfolded_sub_b:
; CHECK: // %bb.0:
; CHECK-NEXT: neg w8, w1
; CHECK-NEXT: and x8, x8, #0x3f
; CHECK-NEXT: sub x8, x8, x2
; CHECK-NEXT: lsr x0, x0, x8
; CHECK-NEXT: ret
%nega = sub i64 0, %a
%negaaddbitwidth = and i64 %nega, 63
%negaaddbitwidthsubb = sub i64 %negaaddbitwidth, %b
%shifted = lshr i64 %val, %negaaddbitwidthsubb
ret i64 %shifted
}
define i32 @reg32_lshr_by_masked_b_sub_negated_unfolded(i32 %val, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: reg32_lshr_by_masked_b_sub_negated_unfolded:
; CHECK: // %bb.0:
; CHECK-NEXT: neg w8, w1
; CHECK-NEXT: and w8, w8, #0x1f
; CHECK-NEXT: sub w8, w2, w8
; CHECK-NEXT: lsr w0, w0, w8
; CHECK-NEXT: ret
%nega = sub i32 0, %a
%negaaddbitwidth = and i32 %nega, 31
%negaaddbitwidthsubb = sub i32 %b, %negaaddbitwidth
%shifted = lshr i32 %val, %negaaddbitwidthsubb
ret i32 %shifted
}
define i64 @reg64_lshr_by_masked_b_sub_negated_unfolded(i64 %val, i64 %a, i64 %b) nounwind {
; CHECK-LABEL: reg64_lshr_by_masked_b_sub_negated_unfolded:
; CHECK: // %bb.0:
; CHECK-NEXT: neg w8, w1
; CHECK-NEXT: and x8, x8, #0x3f
; CHECK-NEXT: sub x8, x2, x8
; CHECK-NEXT: lsr x0, x0, x8
; CHECK-NEXT: ret
%nega = sub i64 0, %a
%negaaddbitwidth = and i64 %nega, 63
%negaaddbitwidthsubb = sub i64 %b, %negaaddbitwidth
%shifted = lshr i64 %val, %negaaddbitwidthsubb
ret i64 %shifted
}
define i32 @reg32_lshr_by_masked_negated_unfolded_add_b(i32 %val, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: reg32_lshr_by_masked_negated_unfolded_add_b:
; CHECK: // %bb.0:
; CHECK-NEXT: neg w8, w1
; CHECK-NEXT: and w8, w8, #0x1f
; CHECK-NEXT: add w8, w8, w2
; CHECK-NEXT: lsr w0, w0, w8
; CHECK-NEXT: ret
%nega = sub i32 0, %a
%negaaddbitwidth = and i32 %nega, 31
%negaaddbitwidthaddb = add i32 %negaaddbitwidth, %b
%shifted = lshr i32 %val, %negaaddbitwidthaddb
ret i32 %shifted
}
define i64 @reg64_lshr_by_masked_negated_unfolded_add_b(i64 %val, i64 %a, i64 %b) nounwind {
; CHECK-LABEL: reg64_lshr_by_masked_negated_unfolded_add_b:
; CHECK: // %bb.0:
; CHECK-NEXT: neg w8, w1
; CHECK-NEXT: and x8, x8, #0x3f
; CHECK-NEXT: add x8, x8, x2
; CHECK-NEXT: lsr x0, x0, x8
; CHECK-NEXT: ret
%nega = sub i64 0, %a
%negaaddbitwidth = and i64 %nega, 63
%negaaddbitwidthaddb = add i64 %negaaddbitwidth, %b
%shifted = lshr i64 %val, %negaaddbitwidthaddb
ret i64 %shifted
}
define i32 @t(i64 %x) {
; CHECK-LABEL: t:
; CHECK: // %bb.0:
; CHECK-NEXT: ubfx x0, x0, #17, #28
; CHECK-NEXT: // kill: def $w0 killed $w0 killed $x0
; CHECK-NEXT: ret
%s = lshr i64 %x, 13
%t = trunc i64 %s to i32
%r = lshr i32 %t, 4
ret i32 %r
}