xref: /llvm-project/llvm/unittests/CodeGen/GlobalISel/ConstantFoldingTest.cpp (revision 7fc871591f1399cd88ff301ed84fa67dc3bf7a6b)
1 //===- ConstantFoldingTest.cpp -------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "GISelMITest.h"
10 #include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
11 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
12 #include "llvm/CodeGen/GlobalISel/Utils.h"
13 #include "llvm/CodeGen/MachineFunction.h"
14 #include "gtest/gtest.h"
15 
16 using namespace llvm;
17 
18 namespace {
19 
TEST_F(AArch64GISelMITest,FoldWithBuilder)20 TEST_F(AArch64GISelMITest, FoldWithBuilder) {
21   setUp();
22   if (!TM)
23     GTEST_SKIP();
24   // Try to use the FoldableInstructionsBuilder to build binary ops.
25   CSEMIRBuilder CFB(B.getState());
26   LLT s32 = LLT::scalar(32);
27   int64_t Cst;
28   auto MIBCAdd =
29       CFB.buildAdd(s32, CFB.buildConstant(s32, 0), CFB.buildConstant(s32, 1));
30   // This should be a constant now.
31   bool match = mi_match(MIBCAdd.getReg(0), *MRI, m_ICst(Cst));
32   EXPECT_TRUE(match);
33   EXPECT_EQ(Cst, 1);
34   auto MIBCAdd1 =
35       CFB.buildInstr(TargetOpcode::G_ADD, {s32},
36                      {CFB.buildConstant(s32, 0), CFB.buildConstant(s32, 1)});
37   // This should be a constant now.
38   match = mi_match(MIBCAdd1.getReg(0), *MRI, m_ICst(Cst));
39   EXPECT_TRUE(match);
40   EXPECT_EQ(Cst, 1);
41 
42   // Try one of the other constructors of MachineIRBuilder to make sure it's
43   // compatible.
44   CSEMIRBuilder CFB1(*MF);
45   CFB1.setInsertPt(*EntryMBB, EntryMBB->end());
46   auto MIBCSub =
47       CFB1.buildInstr(TargetOpcode::G_SUB, {s32},
48                       {CFB1.buildConstant(s32, 1), CFB1.buildConstant(s32, 1)});
49   // This should be a constant now.
50   match = mi_match(MIBCSub.getReg(0), *MRI, m_ICst(Cst));
51   EXPECT_TRUE(match);
52   EXPECT_EQ(Cst, 0);
53 
54   auto MIBCSext1 =
55       CFB1.buildInstr(TargetOpcode::G_SEXT_INREG, {s32},
56                       {CFB1.buildConstant(s32, 0x01), uint64_t(8)});
57   // This should be a constant now.
58   match = mi_match(MIBCSext1.getReg(0), *MRI, m_ICst(Cst));
59   EXPECT_TRUE(match);
60   EXPECT_EQ(1, Cst);
61 
62   auto MIBCSext2 =
63       CFB1.buildInstr(TargetOpcode::G_SEXT_INREG, {s32},
64                       {CFB1.buildConstant(s32, 0x80), uint64_t(8)});
65   // This should be a constant now.
66   match = mi_match(MIBCSext2.getReg(0), *MRI, m_ICst(Cst));
67   EXPECT_TRUE(match);
68   EXPECT_EQ(-0x80, Cst);
69 }
70 
TEST_F(AArch64GISelMITest,FoldBinOp)71 TEST_F(AArch64GISelMITest, FoldBinOp) {
72   setUp();
73   if (!TM)
74     GTEST_SKIP();
75 
76   LLT s32{LLT::scalar(32)};
77   auto MIBCst1 = B.buildConstant(s32, 16);
78   auto MIBCst2 = B.buildConstant(s32, 9);
79   auto MIBFCst1 = B.buildFConstant(s32, 1.0000001);
80   auto MIBFCst2 = B.buildFConstant(s32, 2.0);
81 
82   // Test G_ADD folding Integer + Mixed Int-Float cases
83   std::optional<APInt> FoldGAddInt = ConstantFoldBinOp(
84       TargetOpcode::G_ADD, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI);
85   EXPECT_TRUE(FoldGAddInt.has_value());
86   EXPECT_EQ(25ULL, FoldGAddInt->getLimitedValue());
87   std::optional<APInt> FoldGAddMix = ConstantFoldBinOp(
88       TargetOpcode::G_ADD, MIBCst1.getReg(0), MIBFCst2.getReg(0), *MRI);
89   EXPECT_TRUE(FoldGAddMix.has_value());
90   EXPECT_EQ(1073741840ULL, FoldGAddMix->getLimitedValue());
91 
92   // Test G_AND folding Integer + Mixed Int-Float cases
93   std::optional<APInt> FoldGAndInt = ConstantFoldBinOp(
94       TargetOpcode::G_AND, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI);
95   EXPECT_TRUE(FoldGAndInt.has_value());
96   EXPECT_EQ(0ULL, FoldGAndInt->getLimitedValue());
97   std::optional<APInt> FoldGAndMix = ConstantFoldBinOp(
98       TargetOpcode::G_AND, MIBCst2.getReg(0), MIBFCst1.getReg(0), *MRI);
99   EXPECT_TRUE(FoldGAndMix.has_value());
100   EXPECT_EQ(1ULL, FoldGAndMix->getLimitedValue());
101 
102   // Test G_ASHR folding Integer + Mixed cases
103   std::optional<APInt> FoldGAShrInt = ConstantFoldBinOp(
104       TargetOpcode::G_ASHR, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI);
105   EXPECT_TRUE(FoldGAShrInt.has_value());
106   EXPECT_EQ(0ULL, FoldGAShrInt->getLimitedValue());
107   std::optional<APInt> FoldGAShrMix = ConstantFoldBinOp(
108       TargetOpcode::G_ASHR, MIBFCst2.getReg(0), MIBCst2.getReg(0), *MRI);
109   EXPECT_TRUE(FoldGAShrMix.has_value());
110   EXPECT_EQ(2097152ULL, FoldGAShrMix->getLimitedValue());
111 
112   // Test G_LSHR folding Integer + Mixed Int-Float cases
113   std::optional<APInt> FoldGLShrInt = ConstantFoldBinOp(
114       TargetOpcode::G_LSHR, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI);
115   EXPECT_TRUE(FoldGLShrInt.has_value());
116   EXPECT_EQ(0ULL, FoldGLShrInt->getLimitedValue());
117   std::optional<APInt> FoldGLShrMix = ConstantFoldBinOp(
118       TargetOpcode::G_LSHR, MIBFCst1.getReg(0), MIBCst2.getReg(0), *MRI);
119   EXPECT_TRUE(FoldGLShrMix.has_value());
120   EXPECT_EQ(2080768ULL, FoldGLShrMix->getLimitedValue());
121 
122   // Test G_MUL folding Integer + Mixed Int-Float cases
123   std::optional<APInt> FoldGMulInt = ConstantFoldBinOp(
124       TargetOpcode::G_MUL, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI);
125   EXPECT_TRUE(FoldGMulInt.has_value());
126   EXPECT_EQ(144ULL, FoldGMulInt->getLimitedValue());
127   std::optional<APInt> FoldGMulMix = ConstantFoldBinOp(
128       TargetOpcode::G_MUL, MIBCst1.getReg(0), MIBFCst2.getReg(0), *MRI);
129   EXPECT_TRUE(FoldGMulMix.has_value());
130   EXPECT_EQ(0ULL, FoldGMulMix->getLimitedValue());
131 
132   // Test G_OR folding Integer + Mixed Int-Float cases
133   std::optional<APInt> FoldGOrInt = ConstantFoldBinOp(
134       TargetOpcode::G_OR, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI);
135   EXPECT_TRUE(FoldGOrInt.has_value());
136   EXPECT_EQ(25ULL, FoldGOrInt->getLimitedValue());
137   std::optional<APInt> FoldGOrMix = ConstantFoldBinOp(
138       TargetOpcode::G_OR, MIBCst1.getReg(0), MIBFCst2.getReg(0), *MRI);
139   EXPECT_TRUE(FoldGOrMix.has_value());
140   EXPECT_EQ(1073741840ULL, FoldGOrMix->getLimitedValue());
141 
142   // Test G_SHL folding Integer + Mixed Int-Float cases
143   std::optional<APInt> FoldGShlInt = ConstantFoldBinOp(
144       TargetOpcode::G_SHL, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI);
145   EXPECT_TRUE(FoldGShlInt.has_value());
146   EXPECT_EQ(8192ULL, FoldGShlInt->getLimitedValue());
147   std::optional<APInt> FoldGShlMix = ConstantFoldBinOp(
148       TargetOpcode::G_SHL, MIBCst1.getReg(0), MIBFCst2.getReg(0), *MRI);
149   EXPECT_TRUE(FoldGShlMix.has_value());
150   EXPECT_EQ(0ULL, FoldGShlMix->getLimitedValue());
151 
152   // Test G_SUB folding Integer + Mixed Int-Float cases
153   std::optional<APInt> FoldGSubInt = ConstantFoldBinOp(
154       TargetOpcode::G_SUB, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI);
155   EXPECT_TRUE(FoldGSubInt.has_value());
156   EXPECT_EQ(7ULL, FoldGSubInt->getLimitedValue());
157   std::optional<APInt> FoldGSubMix = ConstantFoldBinOp(
158       TargetOpcode::G_SUB, MIBCst1.getReg(0), MIBFCst2.getReg(0), *MRI);
159   EXPECT_TRUE(FoldGSubMix.has_value());
160   EXPECT_EQ(3221225488ULL, FoldGSubMix->getLimitedValue());
161 
162   // Test G_XOR folding Integer + Mixed Int-Float cases
163   std::optional<APInt> FoldGXorInt = ConstantFoldBinOp(
164       TargetOpcode::G_XOR, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI);
165   EXPECT_TRUE(FoldGXorInt.has_value());
166   EXPECT_EQ(25ULL, FoldGXorInt->getLimitedValue());
167   std::optional<APInt> FoldGXorMix = ConstantFoldBinOp(
168       TargetOpcode::G_XOR, MIBCst1.getReg(0), MIBFCst2.getReg(0), *MRI);
169   EXPECT_TRUE(FoldGXorMix.has_value());
170   EXPECT_EQ(1073741840ULL, FoldGXorMix->getLimitedValue());
171 
172   // Test G_UDIV folding Integer + Mixed Int-Float cases
173   std::optional<APInt> FoldGUdivInt = ConstantFoldBinOp(
174       TargetOpcode::G_UDIV, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI);
175   EXPECT_TRUE(FoldGUdivInt.has_value());
176   EXPECT_EQ(1ULL, FoldGUdivInt->getLimitedValue());
177   std::optional<APInt> FoldGUdivMix = ConstantFoldBinOp(
178       TargetOpcode::G_UDIV, MIBCst1.getReg(0), MIBFCst2.getReg(0), *MRI);
179   EXPECT_TRUE(FoldGUdivMix.has_value());
180   EXPECT_EQ(0ULL, FoldGUdivMix->getLimitedValue());
181 
182   // Test G_SDIV folding Integer + Mixed Int-Float cases
183   std::optional<APInt> FoldGSdivInt = ConstantFoldBinOp(
184       TargetOpcode::G_SDIV, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI);
185   EXPECT_TRUE(FoldGSdivInt.has_value());
186   EXPECT_EQ(1ULL, FoldGSdivInt->getLimitedValue());
187   std::optional<APInt> FoldGSdivMix = ConstantFoldBinOp(
188       TargetOpcode::G_SDIV, MIBCst1.getReg(0), MIBFCst2.getReg(0), *MRI);
189   EXPECT_TRUE(FoldGSdivMix.has_value());
190   EXPECT_EQ(0ULL, FoldGSdivMix->getLimitedValue());
191 
192   // Test G_UREM folding Integer + Mixed Int-Float cases
193   std::optional<APInt> FoldGUremInt = ConstantFoldBinOp(
194       TargetOpcode::G_UDIV, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI);
195   EXPECT_TRUE(FoldGUremInt.has_value());
196   EXPECT_EQ(1ULL, FoldGUremInt->getLimitedValue());
197   std::optional<APInt> FoldGUremMix = ConstantFoldBinOp(
198       TargetOpcode::G_UDIV, MIBCst1.getReg(0), MIBFCst2.getReg(0), *MRI);
199   EXPECT_TRUE(FoldGUremMix.has_value());
200   EXPECT_EQ(0ULL, FoldGUremMix->getLimitedValue());
201 
202   // Test G_SREM folding Integer + Mixed Int-Float cases
203   std::optional<APInt> FoldGSremInt = ConstantFoldBinOp(
204       TargetOpcode::G_SREM, MIBCst1.getReg(0), MIBCst2.getReg(0), *MRI);
205   EXPECT_TRUE(FoldGSremInt.has_value());
206   EXPECT_EQ(7ULL, FoldGSremInt->getLimitedValue());
207   std::optional<APInt> FoldGSremMix = ConstantFoldBinOp(
208       TargetOpcode::G_SREM, MIBCst1.getReg(0), MIBFCst2.getReg(0), *MRI);
209   EXPECT_TRUE(FoldGSremMix.has_value());
210   EXPECT_EQ(16ULL, FoldGSremMix->getLimitedValue());
211 }
212 
213 } // namespace
214