2019-01-16 01:40:37 +01:00
|
|
|
//===- CSETest.cpp -----------------------------------------------===//
|
|
|
|
//
|
2019-01-19 09:50:56 +01:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2019-01-16 01:40:37 +01:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "GISelMITest.h"
|
|
|
|
#include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
TEST_F(GISelMITest, TestCSE) {
|
|
|
|
if (!TM)
|
|
|
|
return;
|
|
|
|
|
|
|
|
LLT s16{LLT::scalar(16)};
|
|
|
|
LLT s32{LLT::scalar(32)};
|
|
|
|
auto MIBInput = B.buildInstr(TargetOpcode::G_TRUNC, {s16}, {Copies[0]});
|
|
|
|
auto MIBInput1 = B.buildInstr(TargetOpcode::G_TRUNC, {s16}, {Copies[1]});
|
|
|
|
auto MIBAdd = B.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
|
|
|
|
GISelCSEInfo CSEInfo;
|
2019-04-15 06:53:46 +02:00
|
|
|
CSEInfo.setCSEConfig(make_unique<CSEConfigFull>());
|
2019-01-16 01:40:37 +01:00
|
|
|
CSEInfo.analyze(*MF);
|
|
|
|
B.setCSEInfo(&CSEInfo);
|
|
|
|
CSEMIRBuilder CSEB(B.getState());
|
2019-02-04 20:15:50 +01:00
|
|
|
|
2019-01-16 01:40:37 +01:00
|
|
|
CSEB.setInsertPt(*EntryMBB, EntryMBB->begin());
|
|
|
|
unsigned AddReg = MRI->createGenericVirtualRegister(s16);
|
|
|
|
auto MIBAddCopy =
|
|
|
|
CSEB.buildInstr(TargetOpcode::G_ADD, {AddReg}, {MIBInput, MIBInput});
|
2019-02-04 19:58:27 +01:00
|
|
|
EXPECT_EQ(MIBAddCopy->getOpcode(), TargetOpcode::COPY);
|
2019-01-16 01:40:37 +01:00
|
|
|
auto MIBAdd2 =
|
|
|
|
CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
|
2019-02-04 19:58:27 +01:00
|
|
|
EXPECT_TRUE(&*MIBAdd == &*MIBAdd2);
|
2019-01-16 01:40:37 +01:00
|
|
|
auto MIBAdd4 =
|
|
|
|
CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
|
2019-02-04 19:58:27 +01:00
|
|
|
EXPECT_TRUE(&*MIBAdd == &*MIBAdd4);
|
2019-01-16 01:40:37 +01:00
|
|
|
auto MIBAdd5 =
|
|
|
|
CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput1});
|
2019-02-04 19:58:27 +01:00
|
|
|
EXPECT_TRUE(&*MIBAdd != &*MIBAdd5);
|
2019-01-16 01:40:37 +01:00
|
|
|
|
|
|
|
// Try building G_CONSTANTS.
|
|
|
|
auto MIBCst = CSEB.buildConstant(s32, 0);
|
|
|
|
auto MIBCst1 = CSEB.buildConstant(s32, 0);
|
2019-02-04 19:58:27 +01:00
|
|
|
EXPECT_TRUE(&*MIBCst == &*MIBCst1);
|
2019-01-16 01:40:37 +01:00
|
|
|
// Try the CFing of BinaryOps.
|
|
|
|
auto MIBCF1 = CSEB.buildInstr(TargetOpcode::G_ADD, {s32}, {MIBCst, MIBCst});
|
2019-02-04 19:58:27 +01:00
|
|
|
EXPECT_TRUE(&*MIBCF1 == &*MIBCst);
|
2019-01-16 01:40:37 +01:00
|
|
|
|
|
|
|
// Try out building FCONSTANTs.
|
|
|
|
auto MIBFP0 = CSEB.buildFConstant(s32, 1.0);
|
|
|
|
auto MIBFP0_1 = CSEB.buildFConstant(s32, 1.0);
|
2019-02-04 19:58:27 +01:00
|
|
|
EXPECT_TRUE(&*MIBFP0 == &*MIBFP0_1);
|
2019-01-16 01:40:37 +01:00
|
|
|
CSEInfo.print();
|
|
|
|
|
2019-02-04 20:15:50 +01:00
|
|
|
// Make sure buildConstant with a vector type doesn't crash, and the elements
|
|
|
|
// CSE.
|
|
|
|
auto Splat0 = CSEB.buildConstant(LLT::vector(2, s32), 0);
|
|
|
|
EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR, Splat0->getOpcode());
|
|
|
|
EXPECT_EQ(Splat0->getOperand(1).getReg(), Splat0->getOperand(2).getReg());
|
|
|
|
EXPECT_EQ(&*MIBCst, MRI->getVRegDef(Splat0->getOperand(1).getReg()));
|
|
|
|
|
|
|
|
auto FSplat = CSEB.buildFConstant(LLT::vector(2, s32), 1.0);
|
|
|
|
EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR, FSplat->getOpcode());
|
|
|
|
EXPECT_EQ(FSplat->getOperand(1).getReg(), FSplat->getOperand(2).getReg());
|
|
|
|
EXPECT_EQ(&*MIBFP0, MRI->getVRegDef(FSplat->getOperand(1).getReg()));
|
|
|
|
|
2019-01-16 01:40:37 +01:00
|
|
|
// Check G_UNMERGE_VALUES
|
|
|
|
auto MIBUnmerge = CSEB.buildUnmerge({s32, s32}, Copies[0]);
|
|
|
|
auto MIBUnmerge2 = CSEB.buildUnmerge({s32, s32}, Copies[0]);
|
2019-02-04 19:58:27 +01:00
|
|
|
EXPECT_TRUE(&*MIBUnmerge == &*MIBUnmerge2);
|
2019-01-16 01:40:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(GISelMITest, TestCSEConstantConfig) {
|
|
|
|
if (!TM)
|
|
|
|
return;
|
|
|
|
|
|
|
|
LLT s16{LLT::scalar(16)};
|
|
|
|
auto MIBInput = B.buildInstr(TargetOpcode::G_TRUNC, {s16}, {Copies[0]});
|
|
|
|
auto MIBAdd = B.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
|
|
|
|
auto MIBZero = B.buildConstant(s16, 0);
|
|
|
|
GISelCSEInfo CSEInfo;
|
|
|
|
CSEInfo.setCSEConfig(make_unique<CSEConfigConstantOnly>());
|
|
|
|
CSEInfo.analyze(*MF);
|
|
|
|
B.setCSEInfo(&CSEInfo);
|
|
|
|
CSEMIRBuilder CSEB(B.getState());
|
|
|
|
CSEB.setInsertPt(*EntryMBB, EntryMBB->begin());
|
|
|
|
auto MIBAdd1 =
|
|
|
|
CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
|
|
|
|
// We should CSE constants only. Adds should not be CSEd.
|
2019-02-04 19:58:27 +01:00
|
|
|
EXPECT_TRUE(MIBAdd1->getOpcode() != TargetOpcode::COPY);
|
|
|
|
EXPECT_TRUE(&*MIBAdd1 != &*MIBAdd);
|
2019-01-16 01:40:37 +01:00
|
|
|
// We should CSE constant.
|
|
|
|
auto MIBZeroTmp = CSEB.buildConstant(s16, 0);
|
2019-02-04 19:58:27 +01:00
|
|
|
EXPECT_TRUE(&*MIBZero == &*MIBZeroTmp);
|
2019-01-16 01:40:37 +01:00
|
|
|
}
|
|
|
|
} // namespace
|