mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-17 03:30:28 +00:00
04402a6c13
AVX is available, and generally tidy up things surrounding UNPCK formation. Originally, I was thinking that the only advantage of PSHUFD over UNPCK instruction variants was its free copy, and otherwise we should use the shorter encoding UNPCK instructions. This isn't right though, there is a larger advantage of being able to fold a load into the operand of a PSHUFD. For UNPCK, the operand *must* be in a register so it can be the second input. This removes the UNPCK formation in the target-specific DAG combine for v4i32 shuffles. It also lifts the v8 and v16 cases out of the AVX-specific check as they are potentially replacing multiple instructions with a single instruction and so should always be valuable. The floating point checks are simplified accordingly. This also adjusts the formation of PSHUFD instructions to attempt to match the shuffle mask to one which would fit an UNPCK instruction variant. This was originally motivated to allow it to match the UNPCK instructions in the combiner, but clearly won't now. Eventually, we should add a MachineCombiner pass that can form UNPCK instructions post-RA when the operand is known to be in a register and thus there is no loss. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@217755 91177308-0d34-0410-b5e6-96231b3b80d8
129 lines
5.2 KiB
LLVM
129 lines
5.2 KiB
LLVM
; RUN: llc -O3 -mtriple=x86_64-apple-macosx -o - < %s -mattr=+avx2 -enable-unsafe-fp-math -mcpu=core2 | FileCheck %s
|
|
; Check that the ExeDepsFix pass correctly fixes the domain for broadcast instructions.
|
|
; <rdar://problem/16354675>
|
|
|
|
; CHECK-LABEL: ExeDepsFix_broadcastss
|
|
; CHECK: broadcastss
|
|
; CHECK: vandps
|
|
; CHECK: vmaxps
|
|
; CHECK: ret
|
|
define <4 x float> @ExeDepsFix_broadcastss(<4 x float> %arg, <4 x float> %arg2) {
|
|
%bitcast = bitcast <4 x float> %arg to <4 x i32>
|
|
%and = and <4 x i32> %bitcast, <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647>
|
|
%floatcast = bitcast <4 x i32> %and to <4 x float>
|
|
%max_is_x = fcmp oge <4 x float> %floatcast, %arg2
|
|
%max = select <4 x i1> %max_is_x, <4 x float> %floatcast, <4 x float> %arg2
|
|
ret <4 x float> %max
|
|
}
|
|
|
|
; CHECK-LABEL: ExeDepsFix_broadcastss256
|
|
; CHECK: broadcastss
|
|
; CHECK: vandps
|
|
; CHECK: vmaxps
|
|
; CHECK: ret
|
|
define <8 x float> @ExeDepsFix_broadcastss256(<8 x float> %arg, <8 x float> %arg2) {
|
|
%bitcast = bitcast <8 x float> %arg to <8 x i32>
|
|
%and = and <8 x i32> %bitcast, <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647>
|
|
%floatcast = bitcast <8 x i32> %and to <8 x float>
|
|
%max_is_x = fcmp oge <8 x float> %floatcast, %arg2
|
|
%max = select <8 x i1> %max_is_x, <8 x float> %floatcast, <8 x float> %arg2
|
|
ret <8 x float> %max
|
|
}
|
|
|
|
|
|
; CHECK-LABEL: ExeDepsFix_broadcastss_inreg
|
|
; CHECK: broadcastss
|
|
; CHECK: vandps
|
|
; CHECK: vmaxps
|
|
; CHECK: ret
|
|
define <4 x float> @ExeDepsFix_broadcastss_inreg(<4 x float> %arg, <4 x float> %arg2, i32 %broadcastvalue) {
|
|
%bitcast = bitcast <4 x float> %arg to <4 x i32>
|
|
%in = insertelement <4 x i32> undef, i32 %broadcastvalue, i32 0
|
|
%mask = shufflevector <4 x i32> %in, <4 x i32> undef, <4 x i32> zeroinitializer
|
|
%and = and <4 x i32> %bitcast, %mask
|
|
%floatcast = bitcast <4 x i32> %and to <4 x float>
|
|
%max_is_x = fcmp oge <4 x float> %floatcast, %arg2
|
|
%max = select <4 x i1> %max_is_x, <4 x float> %floatcast, <4 x float> %arg2
|
|
ret <4 x float> %max
|
|
}
|
|
|
|
; CHECK-LABEL: ExeDepsFix_broadcastss256_inreg
|
|
; CHECK: broadcastss
|
|
; CHECK: vandps
|
|
; CHECK: vmaxps
|
|
; CHECK: ret
|
|
define <8 x float> @ExeDepsFix_broadcastss256_inreg(<8 x float> %arg, <8 x float> %arg2, i32 %broadcastvalue) {
|
|
%bitcast = bitcast <8 x float> %arg to <8 x i32>
|
|
%in = insertelement <8 x i32> undef, i32 %broadcastvalue, i32 0
|
|
%mask = shufflevector <8 x i32> %in, <8 x i32> undef, <8 x i32> zeroinitializer
|
|
%and = and <8 x i32> %bitcast, %mask
|
|
%floatcast = bitcast <8 x i32> %and to <8 x float>
|
|
%max_is_x = fcmp oge <8 x float> %floatcast, %arg2
|
|
%max = select <8 x i1> %max_is_x, <8 x float> %floatcast, <8 x float> %arg2
|
|
ret <8 x float> %max
|
|
}
|
|
|
|
; CHECK-LABEL: ExeDepsFix_broadcastsd
|
|
; In that case the broadcast is directly folded into vandpd.
|
|
; CHECK: vandpd
|
|
; CHECK: vmaxpd
|
|
; CHECK:ret
|
|
define <2 x double> @ExeDepsFix_broadcastsd(<2 x double> %arg, <2 x double> %arg2) {
|
|
%bitcast = bitcast <2 x double> %arg to <2 x i64>
|
|
%and = and <2 x i64> %bitcast, <i64 2147483647, i64 2147483647>
|
|
%floatcast = bitcast <2 x i64> %and to <2 x double>
|
|
%max_is_x = fcmp oge <2 x double> %floatcast, %arg2
|
|
%max = select <2 x i1> %max_is_x, <2 x double> %floatcast, <2 x double> %arg2
|
|
ret <2 x double> %max
|
|
}
|
|
|
|
; CHECK-LABEL: ExeDepsFix_broadcastsd256
|
|
; CHECK: broadcastsd
|
|
; CHECK: vandpd
|
|
; CHECK: vmaxpd
|
|
; CHECK: ret
|
|
define <4 x double> @ExeDepsFix_broadcastsd256(<4 x double> %arg, <4 x double> %arg2) {
|
|
%bitcast = bitcast <4 x double> %arg to <4 x i64>
|
|
%and = and <4 x i64> %bitcast, <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
|
|
%floatcast = bitcast <4 x i64> %and to <4 x double>
|
|
%max_is_x = fcmp oge <4 x double> %floatcast, %arg2
|
|
%max = select <4 x i1> %max_is_x, <4 x double> %floatcast, <4 x double> %arg2
|
|
ret <4 x double> %max
|
|
}
|
|
|
|
|
|
; CHECK-LABEL: ExeDepsFix_broadcastsd_inreg
|
|
; ExeDepsFix works top down, thus it coalesces vpunpcklqdq domain with
|
|
; vpand and there is nothing more you can do to match vmaxpd.
|
|
; CHECK: vmovlhps
|
|
; CHECK: vandps
|
|
; CHECK: vmaxpd
|
|
; CHECK: ret
|
|
define <2 x double> @ExeDepsFix_broadcastsd_inreg(<2 x double> %arg, <2 x double> %arg2, i64 %broadcastvalue) {
|
|
%bitcast = bitcast <2 x double> %arg to <2 x i64>
|
|
%in = insertelement <2 x i64> undef, i64 %broadcastvalue, i32 0
|
|
%mask = shufflevector <2 x i64> %in, <2 x i64> undef, <2 x i32> zeroinitializer
|
|
%and = and <2 x i64> %bitcast, %mask
|
|
%floatcast = bitcast <2 x i64> %and to <2 x double>
|
|
%max_is_x = fcmp oge <2 x double> %floatcast, %arg2
|
|
%max = select <2 x i1> %max_is_x, <2 x double> %floatcast, <2 x double> %arg2
|
|
ret <2 x double> %max
|
|
}
|
|
|
|
; CHECK-LABEL: ExeDepsFix_broadcastsd256_inreg
|
|
; CHECK: broadcastsd
|
|
; CHECK: vandpd
|
|
; CHECK: vmaxpd
|
|
; CHECK: ret
|
|
define <4 x double> @ExeDepsFix_broadcastsd256_inreg(<4 x double> %arg, <4 x double> %arg2, i64 %broadcastvalue) {
|
|
%bitcast = bitcast <4 x double> %arg to <4 x i64>
|
|
%in = insertelement <4 x i64> undef, i64 %broadcastvalue, i32 0
|
|
%mask = shufflevector <4 x i64> %in, <4 x i64> undef, <4 x i32> zeroinitializer
|
|
%and = and <4 x i64> %bitcast, %mask
|
|
%floatcast = bitcast <4 x i64> %and to <4 x double>
|
|
%max_is_x = fcmp oge <4 x double> %floatcast, %arg2
|
|
%max = select <4 x i1> %max_is_x, <4 x double> %floatcast, <4 x double> %arg2
|
|
ret <4 x double> %max
|
|
}
|
|
|