[InstCombine] move shuffle after fma with same-shuffled operands

https://alive2.llvm.org/ce/z/sD-JVv

This extends 432c199e84 with a 3 arg intrinsic to demonstrate
that the code works with the extra operand.

Eventually, we will want to use llvm::isTriviallyVectorizable()
or create some new API for this list, but for now, I am intentionally
making a minimum change to reduce risk and only affect an intrinsic
with regression tests in place.
This commit is contained in:
Sanjay Patel
2022-05-04 11:17:25 -04:00
parent 03e36d8c0e
commit 9c4770eaab
2 changed files with 21 additions and 11 deletions

View File

@@ -1088,8 +1088,16 @@ foldShuffledIntrinsicOperands(IntrinsicInst *II,
// TODO: This should be extended to handle other intrinsics like fshl, ctpop,
// etc. Use llvm::isTriviallyVectorizable() and related to determine
// which intrinsics are safe to shuffle?
if (!match(II, m_MaxOrMin(m_Value(), m_Value())))
switch (II->getIntrinsicID()) {
case Intrinsic::smax:
case Intrinsic::smin:
case Intrinsic::umax:
case Intrinsic::umin:
case Intrinsic::fma:
break;
default:
return nullptr;
}
Value *X;
ArrayRef<int> Mask;

View File

@@ -736,10 +736,8 @@ define <2 x double> @fmuladd_undef_2(<2 x double> %b, <2 x double> %c) {
define <2 x float> @fma_unary_shuffle_ops(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
; CHECK-LABEL: @fma_unary_shuffle_ops(
; CHECK-NEXT: [[A:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
; CHECK-NEXT: [[B:%.*]] = shufflevector <2 x float> [[Y:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
; CHECK-NEXT: [[C:%.*]] = shufflevector <2 x float> [[Z:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
; CHECK-NEXT: [[R:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[A]], <2 x float> [[B]], <2 x float> [[C]])
; CHECK-NEXT: [[TMP1:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]], <2 x float> [[Z:%.*]])
; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
; CHECK-NEXT: ret <2 x float> [[R]]
;
%a = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> <i32 1, i32 0>
@@ -753,9 +751,8 @@ define <3 x float> @fma_unary_shuffle_ops_widening(<2 x float> %x, <2 x float> %
; CHECK-LABEL: @fma_unary_shuffle_ops_widening(
; CHECK-NEXT: [[A:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <3 x i32> <i32 1, i32 0, i32 1>
; CHECK-NEXT: call void @use_vec3(<3 x float> [[A]])
; CHECK-NEXT: [[B:%.*]] = shufflevector <2 x float> [[Y:%.*]], <2 x float> poison, <3 x i32> <i32 1, i32 0, i32 1>
; CHECK-NEXT: [[C:%.*]] = shufflevector <2 x float> [[Z:%.*]], <2 x float> poison, <3 x i32> <i32 1, i32 0, i32 1>
; CHECK-NEXT: [[R:%.*]] = call <3 x float> @llvm.fma.v3f32(<3 x float> [[A]], <3 x float> [[B]], <3 x float> [[C]])
; CHECK-NEXT: [[TMP1:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[X]], <2 x float> [[Y:%.*]], <2 x float> [[Z:%.*]])
; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <3 x i32> <i32 1, i32 0, i32 1>
; CHECK-NEXT: ret <3 x float> [[R]]
;
%a = shufflevector <2 x float> %x, <2 x float> poison, <3 x i32> <i32 1, i32 0, i32 1>
@@ -768,11 +765,10 @@ define <3 x float> @fma_unary_shuffle_ops_widening(<2 x float> %x, <2 x float> %
define <2 x float> @fma_unary_shuffle_ops_narrowing(<3 x float> %x, <3 x float> %y, <3 x float> %z) {
; CHECK-LABEL: @fma_unary_shuffle_ops_narrowing(
; CHECK-NEXT: [[A:%.*]] = shufflevector <3 x float> [[X:%.*]], <3 x float> poison, <2 x i32> <i32 1, i32 0>
; CHECK-NEXT: [[B:%.*]] = shufflevector <3 x float> [[Y:%.*]], <3 x float> poison, <2 x i32> <i32 1, i32 0>
; CHECK-NEXT: call void @use_vec(<2 x float> [[B]])
; CHECK-NEXT: [[C:%.*]] = shufflevector <3 x float> [[Z:%.*]], <3 x float> poison, <2 x i32> <i32 1, i32 0>
; CHECK-NEXT: [[R:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[A]], <2 x float> [[B]], <2 x float> [[C]])
; CHECK-NEXT: [[TMP1:%.*]] = call <3 x float> @llvm.fma.v3f32(<3 x float> [[X:%.*]], <3 x float> [[Y]], <3 x float> [[Z:%.*]])
; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x float> [[TMP1]], <3 x float> poison, <2 x i32> <i32 1, i32 0>
; CHECK-NEXT: ret <2 x float> [[R]]
;
%a = shufflevector <3 x float> %x, <3 x float> poison, <2 x i32> <i32 1, i32 0>
@@ -783,6 +779,8 @@ define <2 x float> @fma_unary_shuffle_ops_narrowing(<3 x float> %x, <3 x float>
ret <2 x float> %r
}
; negative test - must have 3 shuffles
define <2 x float> @fma_unary_shuffle_ops_unshuffled(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
; CHECK-LABEL: @fma_unary_shuffle_ops_unshuffled(
; CHECK-NEXT: [[A:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
@@ -796,6 +794,8 @@ define <2 x float> @fma_unary_shuffle_ops_unshuffled(<2 x float> %x, <2 x float>
ret <2 x float> %r
}
; negative test - must have identical masks
define <2 x float> @fma_unary_shuffle_ops_wrong_mask(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
; CHECK-LABEL: @fma_unary_shuffle_ops_wrong_mask(
; CHECK-NEXT: [[A:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
@@ -811,6 +811,8 @@ define <2 x float> @fma_unary_shuffle_ops_wrong_mask(<2 x float> %x, <2 x float>
ret <2 x float> %r
}
; negative test - too many uses
define <2 x float> @fma_unary_shuffle_ops_uses(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
; CHECK-LABEL: @fma_unary_shuffle_ops_uses(
; CHECK-NEXT: [[A:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>