1 //===- OperatorTest.cpp ---------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/SandboxIR/Operator.h"
10 #include "llvm/AsmParser/Parser.h"
11 #include "llvm/SandboxIR/Context.h"
12 #include "llvm/SandboxIR/Function.h"
13 #include "llvm/SandboxIR/Instruction.h"
14 #include "llvm/SandboxIR/Module.h"
15 #include "llvm/SandboxIR/Value.h"
16 #include "llvm/Support/SourceMgr.h"
17 #include "gtest/gtest.h"
21 struct OperatorTest
: public testing::Test
{
23 std::unique_ptr
<Module
> M
;
25 void parseIR(LLVMContext
&C
, const char *IR
) {
27 M
= parseAssemblyString(IR
, Err
, C
);
29 Err
.print("OperatorTest", errs());
31 BasicBlock
*getBasicBlockByName(Function
&F
, StringRef Name
) {
32 for (BasicBlock
&BB
: F
)
33 if (BB
.getName() == Name
)
35 llvm_unreachable("Expected to find basic block!");
39 TEST_F(OperatorTest
, Operator
) {
41 define void @foo(i8 %v1) {
42 %add0 = add i8 %v1, 42
43 %add1 = add nuw i8 %v1, 42
47 llvm::Function
*LLVMF
= &*M
->getFunction("foo");
48 sandboxir::Context
Ctx(C
);
49 sandboxir::Function
*F
= Ctx
.createFunction(LLVMF
);
50 auto *BB
= &*F
->begin();
51 auto It
= BB
->begin();
52 auto *OperatorI0
= cast
<sandboxir::Operator
>(&*It
++);
53 auto *OperatorI1
= cast
<sandboxir::Operator
>(&*It
++);
54 EXPECT_FALSE(OperatorI0
->hasPoisonGeneratingFlags());
55 EXPECT_TRUE(OperatorI1
->hasPoisonGeneratingFlags());
58 TEST_F(OperatorTest
, OverflowingBinaryOperator
) {
60 define void @foo(i8 %v1) {
62 %addNSW = add nsw i8 %v1, 42
63 %addNUW = add nuw i8 %v1, 42
67 llvm::Function
*LLVMF
= &*M
->getFunction("foo");
68 sandboxir::Context
Ctx(C
);
69 sandboxir::Function
*F
= Ctx
.createFunction(LLVMF
);
70 auto *BB
= &*F
->begin();
71 auto It
= BB
->begin();
72 auto *Add
= cast
<sandboxir::OverflowingBinaryOperator
>(&*It
++);
73 auto *AddNSW
= cast
<sandboxir::OverflowingBinaryOperator
>(&*It
++);
74 auto *AddNUW
= cast
<sandboxir::OverflowingBinaryOperator
>(&*It
++);
75 EXPECT_FALSE(Add
->hasNoUnsignedWrap());
76 EXPECT_FALSE(Add
->hasNoSignedWrap());
77 EXPECT_EQ(Add
->getNoWrapKind(), llvm::OverflowingBinaryOperator::AnyWrap
);
79 EXPECT_FALSE(AddNSW
->hasNoUnsignedWrap());
80 EXPECT_TRUE(AddNSW
->hasNoSignedWrap());
81 EXPECT_EQ(AddNSW
->getNoWrapKind(),
82 llvm::OverflowingBinaryOperator::NoSignedWrap
);
84 EXPECT_TRUE(AddNUW
->hasNoUnsignedWrap());
85 EXPECT_FALSE(AddNUW
->hasNoSignedWrap());
86 EXPECT_EQ(AddNUW
->getNoWrapKind(),
87 llvm::OverflowingBinaryOperator::NoUnsignedWrap
);
90 TEST_F(OperatorTest
, FPMathOperator
) {
92 define void @foo(float %v1, double %v2) {
93 %fadd = fadd float %v1, 42.0
94 %Fast = fadd fast float %v1, 42.0
95 %Reassoc = fmul reassoc float %v1, 42.0
96 %NNAN = fmul nnan float %v1, 42.0
97 %NINF = fmul ninf float %v1, 42.0
98 %NSZ = fmul nsz float %v1, 42.0
99 %ARCP = fmul arcp float %v1, 42.0
100 %CONTRACT = fmul contract float %v1, 42.0
101 %AFN = fmul afn double %v2, 42.0
105 llvm::Function
*LLVMF
= &*M
->getFunction("foo");
106 auto *LLVMBB
= &*LLVMF
->begin();
107 auto LLVMIt
= LLVMBB
->begin();
109 sandboxir::Context
Ctx(C
);
110 sandboxir::Function
*F
= Ctx
.createFunction(LLVMF
);
111 auto *BB
= &*F
->begin();
112 auto It
= BB
->begin();
113 auto TermIt
= BB
->getTerminator()->getIterator();
114 while (It
!= TermIt
) {
115 auto *FPM
= cast
<sandboxir::FPMathOperator
>(&*It
++);
116 auto *LLVMFPM
= cast
<llvm::FPMathOperator
>(&*LLVMIt
++);
117 EXPECT_EQ(FPM
->isFast(), LLVMFPM
->isFast());
118 EXPECT_EQ(FPM
->hasAllowReassoc(), LLVMFPM
->hasAllowReassoc());
119 EXPECT_EQ(FPM
->hasNoNaNs(), LLVMFPM
->hasNoNaNs());
120 EXPECT_EQ(FPM
->hasNoInfs(), LLVMFPM
->hasNoInfs());
121 EXPECT_EQ(FPM
->hasNoSignedZeros(), LLVMFPM
->hasNoSignedZeros());
122 EXPECT_EQ(FPM
->hasAllowReciprocal(), LLVMFPM
->hasAllowReciprocal());
123 EXPECT_EQ(FPM
->hasAllowContract(), LLVMFPM
->hasAllowContract());
124 EXPECT_EQ(FPM
->hasApproxFunc(), LLVMFPM
->hasApproxFunc());
126 // There doesn't seem to be an operator== for FastMathFlags so let's do a
127 // string comparison instead.
129 raw_string_ostream
SS1(Str1
);
131 raw_string_ostream
SS2(Str2
);
132 FPM
->getFastMathFlags().print(SS1
);
133 LLVMFPM
->getFastMathFlags().print(SS2
);
134 EXPECT_EQ(Str1
, Str2
);
136 EXPECT_EQ(FPM
->getFPAccuracy(), LLVMFPM
->getFPAccuracy());
138 sandboxir::FPMathOperator::isSupportedFloatingPointType(FPM
->getType()),
139 llvm::FPMathOperator::isSupportedFloatingPointType(LLVMFPM
->getType()));