[llvm] bdd5bfd - [IR][GVN] add/allow commutative intrinsics with >2 args
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 3 07:15:10 PDT 2020
Author: Sanjay Patel
Date: 2020-09-03T10:14:53-04:00
New Revision: bdd5bfd0e434637c44916fe2072b1d80fa022092
URL: https://github.com/llvm/llvm-project/commit/bdd5bfd0e434637c44916fe2072b1d80fa022092
DIFF: https://github.com/llvm/llvm-project/commit/bdd5bfd0e434637c44916fe2072b1d80fa022092.diff
LOG: [IR][GVN] add/allow commutative intrinsics with >2 args
Follow-up to D86798 and rGe25449f.
Added:
Modified:
llvm/include/llvm/IR/IntrinsicInst.h
llvm/lib/Transforms/Scalar/GVN.cpp
llvm/test/Transforms/GVN/commute.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/IntrinsicInst.h b/llvm/include/llvm/IR/IntrinsicInst.h
index c29d20c1729b..9ba9ea68f989 100644
--- a/llvm/include/llvm/IR/IntrinsicInst.h
+++ b/llvm/include/llvm/IR/IntrinsicInst.h
@@ -70,13 +70,12 @@ class IntrinsicInst : public CallInst {
case Intrinsic::uadd_with_overflow:
case Intrinsic::smul_with_overflow:
case Intrinsic::umul_with_overflow:
- // TODO: These fixed-point math intrinsics have commutative first two
- // operands, but callers may not handle instructions with more than
- // two operands.
- // case Intrinsic::smul_fix:
- // case Intrinsic::umul_fix:
- // case Intrinsic::smul_fix_sat:
- // case Intrinsic::umul_fix_sat:
+ case Intrinsic::smul_fix:
+ case Intrinsic::umul_fix:
+ case Intrinsic::smul_fix_sat:
+ case Intrinsic::umul_fix_sat:
+ case Intrinsic::fma:
+ case Intrinsic::fmuladd:
return true;
default:
return false;
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index f8962c085224..c71038d66f99 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -295,9 +295,7 @@ GVN::Expression GVN::ValueTable::createExpr(Instruction *I) {
// of their operands get the same value number by sorting the operand value
// numbers. Since commutative operands are the 1st two operands it is more
// efficient to sort by hand rather than using, say, std::sort.
- assert(((isa<BinaryOperator>(I) && I->getNumOperands() == 2) ||
- (isa<IntrinsicInst>(I) && I->getNumOperands() == 3))
- && "Unsupported commutative instruction!");
+ assert(I->getNumOperands() >= 2 && "Unsupported commutative instruction!");
if (e.varargs[0] > e.varargs[1])
std::swap(e.varargs[0], e.varargs[1]);
e.commutative = true;
@@ -1840,9 +1838,7 @@ uint32_t GVN::ValueTable::phiTranslateImpl(const BasicBlock *Pred,
}
if (Exp.commutative) {
- assert((Exp.varargs.size() == 2 ||
- (Exp.opcode == Instruction::Call && Exp.varargs.size() == 3))
- && "Unsupported commutative instruction!");
+ assert(Exp.varargs.size() >= 2 && "Unsupported commutative instruction!");
if (Exp.varargs[0] > Exp.varargs[1]) {
std::swap(Exp.varargs[0], Exp.varargs[1]);
uint32_t Opcode = Exp.opcode >> 8;
diff --git a/llvm/test/Transforms/GVN/commute.ll b/llvm/test/Transforms/GVN/commute.ll
index d0f26f6e27e6..c76318db56a4 100644
--- a/llvm/test/Transforms/GVN/commute.ll
+++ b/llvm/test/Transforms/GVN/commute.ll
@@ -74,9 +74,7 @@ declare i16 @llvm.umul.fix.i16(i16, i16, i32)
define i16 @intrinsic_3_args(i16 %x, i16 %y) {
; CHECK-LABEL: @intrinsic_3_args(
; CHECK-NEXT: [[M1:%.*]] = call i16 @llvm.smul.fix.i16(i16 [[X:%.*]], i16 [[Y:%.*]], i32 1)
-; CHECK-NEXT: [[M2:%.*]] = call i16 @llvm.smul.fix.i16(i16 [[Y]], i16 [[X]], i32 1)
-; CHECK-NEXT: [[R:%.*]] = sub i16 [[M1]], [[M2]]
-; CHECK-NEXT: ret i16 [[R]]
+; CHECK-NEXT: ret i16 0
;
%m1 = call i16 @llvm.smul.fix.i16(i16 %x, i16 %y, i32 1)
%m2 = call i16 @llvm.smul.fix.i16(i16 %y, i16 %x, i32 1)
@@ -84,6 +82,8 @@ define i16 @intrinsic_3_args(i16 %x, i16 %y) {
ret i16 %r
}
+; Negative test - 3rd arg is
diff erent
+
define i16 @intrinsic_3_args_not_same(i16 %x, i16 %y) {
; CHECK-LABEL: @intrinsic_3_args_not_same(
; CHECK-NEXT: [[M1:%.*]] = call i16 @llvm.umul.fix.i16(i16 [[X:%.*]], i16 [[Y:%.*]], i32 2)
@@ -102,9 +102,7 @@ declare float @llvm.fma.f32(float, float, float)
define float @fma(float %x, float %y) {
; CHECK-LABEL: @fma(
; CHECK-NEXT: [[M1:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], float [[Y:%.*]], float 1.000000e+00)
-; CHECK-NEXT: [[M2:%.*]] = call float @llvm.fma.f32(float [[Y]], float [[X]], float 1.000000e+00)
-; CHECK-NEXT: [[R:%.*]] = fdiv nnan float [[M1]], [[M2]]
-; CHECK-NEXT: ret float [[R]]
+; CHECK-NEXT: ret float 1.000000e+00
;
%m1 = call float @llvm.fma.f32(float %x, float %y, float 1.0)
%m2 = call float @llvm.fma.f32(float %y, float %x, float 1.0)
More information about the llvm-commits
mailing list