blob: 31ad310655577422816c30fbbceee2aa49656c17 [file]
; Verify constant propagation of 64-bit extract operations. The internal left
; shift used to position the bitfield must use unsigned arithmetic to avoid
; undefined behavior when high bits in the source value cause signed overflow.
; RUN: llc -mtriple=hexagon -O2 < %s | FileCheck %s
target triple = "hexagon"
@g0 = common global i64 0, align 8
@g1 = common global i64 0, align 8
; extractup(0xC00000, 15, 8): extract 15 unsigned bits at offset 8.
; The source value 0xC00000 has bit 23 set (outside the [8,23) extraction
; window), which triggers a left shift of the value by 41 that would overflow
; int64_t. Bits [22:8] = 0x4000 = 16384.
define void @test_extractup() #0 {
; CHECK-LABEL: test_extractup:
; CHECK: 16384
; CHECK-NOT: = extractu
entry:
%0 = call i64 @llvm.hexagon.S2.extractup(i64 12582912, i32 15, i32 8)
store i64 %0, ptr @g0, align 8
ret void
}
; extractp(0xC00000, 15, 8): extract 15 signed bits at offset 8.
; Bits [22:8] = 0x4000; bit 14 of the 15-bit field is set (sign bit),
; so the result is sign-extended to -16384.
define void @test_extractp() #0 {
; CHECK-LABEL: test_extractp:
; CHECK: -16384
; CHECK-NOT: = extract
entry:
%0 = call i64 @llvm.hexagon.S4.extractp(i64 12582912, i32 15, i32 8)
store i64 %0, ptr @g1, align 8
ret void
}
declare i64 @llvm.hexagon.S2.extractup(i64, i32, i32) #1
declare i64 @llvm.hexagon.S4.extractp(i64, i32, i32) #1
attributes #0 = { nounwind "less-precise-fpmad"="false" "frame-pointer"="all" }
attributes #1 = { nounwind readnone }