forked from OSchip/llvm-project
[IR][GVN] add/allow commutative intrinsics with >2 args
Follow-up to D86798 and rGe25449f.
This commit is contained in:
parent
4013cfd34d
commit
bdd5bfd0e4
|
@ -70,13 +70,12 @@ public:
|
|||
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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 different
|
||||
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue