xref: /llvm-project/llvm/unittests/SandboxIR/OperatorTest.cpp (revision a24a420c2b4854598ac24a571a8275bfaa1b9159)
154566ba5Svporpo //===- OperatorTest.cpp ---------------------------------------------------===//
254566ba5Svporpo //
354566ba5Svporpo // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
454566ba5Svporpo // See https://llvm.org/LICENSE.txt for license information.
554566ba5Svporpo // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
654566ba5Svporpo //
754566ba5Svporpo //===----------------------------------------------------------------------===//
854566ba5Svporpo 
954566ba5Svporpo #include "llvm/SandboxIR/Operator.h"
1054566ba5Svporpo #include "llvm/AsmParser/Parser.h"
1154566ba5Svporpo #include "llvm/SandboxIR/Context.h"
1254566ba5Svporpo #include "llvm/SandboxIR/Function.h"
1354566ba5Svporpo #include "llvm/SandboxIR/Instruction.h"
1454566ba5Svporpo #include "llvm/SandboxIR/Module.h"
1554566ba5Svporpo #include "llvm/SandboxIR/Value.h"
1654566ba5Svporpo #include "llvm/Support/SourceMgr.h"
1754566ba5Svporpo #include "gtest/gtest.h"
1854566ba5Svporpo 
1954566ba5Svporpo using namespace llvm;
2054566ba5Svporpo 
2154566ba5Svporpo struct OperatorTest : public testing::Test {
2254566ba5Svporpo   LLVMContext C;
2354566ba5Svporpo   std::unique_ptr<Module> M;
2454566ba5Svporpo 
2554566ba5Svporpo   void parseIR(LLVMContext &C, const char *IR) {
2654566ba5Svporpo     SMDiagnostic Err;
2754566ba5Svporpo     M = parseAssemblyString(IR, Err, C);
2854566ba5Svporpo     if (!M)
2954566ba5Svporpo       Err.print("OperatorTest", errs());
3054566ba5Svporpo   }
3154566ba5Svporpo   BasicBlock *getBasicBlockByName(Function &F, StringRef Name) {
3254566ba5Svporpo     for (BasicBlock &BB : F)
3354566ba5Svporpo       if (BB.getName() == Name)
3454566ba5Svporpo         return &BB;
3554566ba5Svporpo     llvm_unreachable("Expected to find basic block!");
3654566ba5Svporpo   }
3754566ba5Svporpo };
3854566ba5Svporpo 
3954566ba5Svporpo TEST_F(OperatorTest, Operator) {
4054566ba5Svporpo   parseIR(C, R"IR(
4154566ba5Svporpo define void @foo(i8 %v1) {
4254566ba5Svporpo   %add0 = add i8 %v1, 42
4354566ba5Svporpo   %add1 = add nuw i8 %v1, 42
4454566ba5Svporpo   ret void
4554566ba5Svporpo }
4654566ba5Svporpo )IR");
4754566ba5Svporpo   llvm::Function *LLVMF = &*M->getFunction("foo");
4854566ba5Svporpo   sandboxir::Context Ctx(C);
4954566ba5Svporpo   sandboxir::Function *F = Ctx.createFunction(LLVMF);
5054566ba5Svporpo   auto *BB = &*F->begin();
5154566ba5Svporpo   auto It = BB->begin();
5254566ba5Svporpo   auto *OperatorI0 = cast<sandboxir::Operator>(&*It++);
5354566ba5Svporpo   auto *OperatorI1 = cast<sandboxir::Operator>(&*It++);
5454566ba5Svporpo   EXPECT_FALSE(OperatorI0->hasPoisonGeneratingFlags());
5554566ba5Svporpo   EXPECT_TRUE(OperatorI1->hasPoisonGeneratingFlags());
5654566ba5Svporpo }
5754566ba5Svporpo 
5854566ba5Svporpo TEST_F(OperatorTest, OverflowingBinaryOperator) {
5954566ba5Svporpo   parseIR(C, R"IR(
6054566ba5Svporpo define void @foo(i8 %v1) {
6154566ba5Svporpo   %add = add i8 %v1, 42
6254566ba5Svporpo   %addNSW = add nsw i8 %v1, 42
6354566ba5Svporpo   %addNUW = add nuw i8 %v1, 42
6454566ba5Svporpo   ret void
6554566ba5Svporpo }
6654566ba5Svporpo )IR");
6754566ba5Svporpo   llvm::Function *LLVMF = &*M->getFunction("foo");
6854566ba5Svporpo   sandboxir::Context Ctx(C);
6954566ba5Svporpo   sandboxir::Function *F = Ctx.createFunction(LLVMF);
7054566ba5Svporpo   auto *BB = &*F->begin();
7154566ba5Svporpo   auto It = BB->begin();
7254566ba5Svporpo   auto *Add = cast<sandboxir::OverflowingBinaryOperator>(&*It++);
7354566ba5Svporpo   auto *AddNSW = cast<sandboxir::OverflowingBinaryOperator>(&*It++);
7454566ba5Svporpo   auto *AddNUW = cast<sandboxir::OverflowingBinaryOperator>(&*It++);
7554566ba5Svporpo   EXPECT_FALSE(Add->hasNoUnsignedWrap());
7654566ba5Svporpo   EXPECT_FALSE(Add->hasNoSignedWrap());
7754566ba5Svporpo   EXPECT_EQ(Add->getNoWrapKind(), llvm::OverflowingBinaryOperator::AnyWrap);
7854566ba5Svporpo 
7954566ba5Svporpo   EXPECT_FALSE(AddNSW->hasNoUnsignedWrap());
8054566ba5Svporpo   EXPECT_TRUE(AddNSW->hasNoSignedWrap());
8154566ba5Svporpo   EXPECT_EQ(AddNSW->getNoWrapKind(),
8254566ba5Svporpo             llvm::OverflowingBinaryOperator::NoSignedWrap);
8354566ba5Svporpo 
8454566ba5Svporpo   EXPECT_TRUE(AddNUW->hasNoUnsignedWrap());
8554566ba5Svporpo   EXPECT_FALSE(AddNUW->hasNoSignedWrap());
8654566ba5Svporpo   EXPECT_EQ(AddNUW->getNoWrapKind(),
8754566ba5Svporpo             llvm::OverflowingBinaryOperator::NoUnsignedWrap);
8854566ba5Svporpo }
89*a24a420cSvporpo 
90*a24a420cSvporpo TEST_F(OperatorTest, FPMathOperator) {
91*a24a420cSvporpo   parseIR(C, R"IR(
92*a24a420cSvporpo define void @foo(float %v1, double %v2) {
93*a24a420cSvporpo   %fadd = fadd float %v1, 42.0
94*a24a420cSvporpo   %Fast = fadd fast float %v1, 42.0
95*a24a420cSvporpo   %Reassoc = fmul reassoc float %v1, 42.0
96*a24a420cSvporpo   %NNAN = fmul nnan float %v1, 42.0
97*a24a420cSvporpo   %NINF = fmul ninf float %v1, 42.0
98*a24a420cSvporpo   %NSZ = fmul nsz float %v1, 42.0
99*a24a420cSvporpo   %ARCP = fmul arcp float %v1, 42.0
100*a24a420cSvporpo   %CONTRACT = fmul contract float %v1, 42.0
101*a24a420cSvporpo   %AFN = fmul afn double %v2, 42.0
102*a24a420cSvporpo   ret void
103*a24a420cSvporpo }
104*a24a420cSvporpo )IR");
105*a24a420cSvporpo   llvm::Function *LLVMF = &*M->getFunction("foo");
106*a24a420cSvporpo   auto *LLVMBB = &*LLVMF->begin();
107*a24a420cSvporpo   auto LLVMIt = LLVMBB->begin();
108*a24a420cSvporpo 
109*a24a420cSvporpo   sandboxir::Context Ctx(C);
110*a24a420cSvporpo   sandboxir::Function *F = Ctx.createFunction(LLVMF);
111*a24a420cSvporpo   auto *BB = &*F->begin();
112*a24a420cSvporpo   auto It = BB->begin();
113*a24a420cSvporpo   auto TermIt = BB->getTerminator()->getIterator();
114*a24a420cSvporpo   while (It != TermIt) {
115*a24a420cSvporpo     auto *FPM = cast<sandboxir::FPMathOperator>(&*It++);
116*a24a420cSvporpo     auto *LLVMFPM = cast<llvm::FPMathOperator>(&*LLVMIt++);
117*a24a420cSvporpo     EXPECT_EQ(FPM->isFast(), LLVMFPM->isFast());
118*a24a420cSvporpo     EXPECT_EQ(FPM->hasAllowReassoc(), LLVMFPM->hasAllowReassoc());
119*a24a420cSvporpo     EXPECT_EQ(FPM->hasNoNaNs(), LLVMFPM->hasNoNaNs());
120*a24a420cSvporpo     EXPECT_EQ(FPM->hasNoInfs(), LLVMFPM->hasNoInfs());
121*a24a420cSvporpo     EXPECT_EQ(FPM->hasNoSignedZeros(), LLVMFPM->hasNoSignedZeros());
122*a24a420cSvporpo     EXPECT_EQ(FPM->hasAllowReciprocal(), LLVMFPM->hasAllowReciprocal());
123*a24a420cSvporpo     EXPECT_EQ(FPM->hasAllowContract(), LLVMFPM->hasAllowContract());
124*a24a420cSvporpo     EXPECT_EQ(FPM->hasApproxFunc(), LLVMFPM->hasApproxFunc());
125*a24a420cSvporpo 
126*a24a420cSvporpo     // There doesn't seem to be an operator== for FastMathFlags so let's do a
127*a24a420cSvporpo     // string comparison instead.
128*a24a420cSvporpo     std::string Str1;
129*a24a420cSvporpo     raw_string_ostream SS1(Str1);
130*a24a420cSvporpo     std::string Str2;
131*a24a420cSvporpo     raw_string_ostream SS2(Str2);
132*a24a420cSvporpo     FPM->getFastMathFlags().print(SS1);
133*a24a420cSvporpo     LLVMFPM->getFastMathFlags().print(SS2);
134*a24a420cSvporpo     EXPECT_EQ(Str1, Str2);
135*a24a420cSvporpo 
136*a24a420cSvporpo     EXPECT_EQ(FPM->getFPAccuracy(), LLVMFPM->getFPAccuracy());
137*a24a420cSvporpo     EXPECT_EQ(
138*a24a420cSvporpo         sandboxir::FPMathOperator::isSupportedFloatingPointType(FPM->getType()),
139*a24a420cSvporpo         llvm::FPMathOperator::isSupportedFloatingPointType(LLVMFPM->getType()));
140*a24a420cSvporpo   }
141*a24a420cSvporpo }
142