From 2bb11d189f6f6aa1137e60396f4170c5435a54a0 Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Mon, 30 Jun 2025 14:33:36 +0100 Subject: [PATCH] [InstCombine] Pull vector reverse through fneg This follows on from https://github.com/llvm/llvm-project/pull/144933#issuecomment-2992372627, and allows us to remove the reverse (fneg (reverse x)) combine. A separate patch will handle the case for fabs. I haven't checked if we perform this canonicalization for either unops or binops for vp.reverse --- .../InstCombine/InstCombineAddSub.cpp | 6 ++++++ .../InstCombine/InstCombineCalls.cpp | 18 +----------------- .../Transforms/InstCombine/vector-reverse.ll | 6 +++--- 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index e721f0cd5f9e3..f727eb0a63e05 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -3049,6 +3049,12 @@ Instruction *InstCombinerImpl::visitFNeg(UnaryOperator &I) { if (match(OneUse, m_Shuffle(m_Value(X), m_Poison(), m_Mask(Mask)))) return new ShuffleVectorInst(Builder.CreateFNegFMF(X, &I), Mask); + // fneg (reverse x) --> reverse (fneg x) + if (match(OneUse, m_VecReverse(m_Value(X)))) { + Value *Reverse = Builder.CreateVectorReverse(Builder.CreateFNegFMF(X, &I)); + return replaceInstUsesWith(I, Reverse); + } + return nullptr; } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index e33d111167c04..47cc424f4ac07 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -3549,23 +3549,6 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { } break; } - case Intrinsic::vector_reverse: { - Value *Vec = II->getArgOperand(0); - // Note: We canonicalize reverse after binops, so we don't need a - // corresponding binop case here. TODO: Consider canonicalizing - // reverse after fneg? - - // rev(unop rev(X)) --> unop X - Value *X; - if (match(Vec, m_OneUse(m_UnOp(m_VecReverse(m_Value(X)))))) { - auto *OldUnOp = cast(Vec); - auto *NewUnOp = UnaryOperator::CreateWithCopiedFlags( - OldUnOp->getOpcode(), X, OldUnOp, OldUnOp->getName(), - II->getIterator()); - return replaceInstUsesWith(CI, NewUnOp); - } - break; - } case Intrinsic::experimental_vp_reverse: { Value *X; Value *Vec = II->getArgOperand(0); @@ -3573,6 +3556,7 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { if (!match(Mask, m_AllOnes())) break; Value *EVL = II->getArgOperand(2); + // TODO: Canonicalize experimental.vp.reverse after unop/binops? // rev(unop rev(X)) --> unop X if (match(Vec, m_OneUse(m_UnOp(m_Intrinsic( diff --git a/llvm/test/Transforms/InstCombine/vector-reverse.ll b/llvm/test/Transforms/InstCombine/vector-reverse.ll index c9c68d2241b34..8421d6082dc44 100644 --- a/llvm/test/Transforms/InstCombine/vector-reverse.ll +++ b/llvm/test/Transforms/InstCombine/vector-reverse.ll @@ -161,9 +161,9 @@ define @binop_reverse_splat_LHS_1( %a, i32 define @unop_reverse( %a) { ; CHECK-LABEL: @unop_reverse( -; CHECK-NEXT: [[A_REV:%.*]] = tail call @llvm.vector.reverse.nxv4f32( [[A:%.*]]) -; CHECK-NEXT: [[NEG:%.*]] = fneg fast [[A_REV]] -; CHECK-NEXT: ret [[NEG]] +; CHECK-NEXT: [[NEG:%.*]] = fneg fast [[A_REV:%.*]] +; CHECK-NEXT: [[NEG1:%.*]] = call @llvm.vector.reverse.nxv4f32( [[NEG]]) +; CHECK-NEXT: ret [[NEG1]] ; %a.rev = tail call @llvm.vector.reverse.nxv4f32( %a) %neg = fneg fast %a.rev