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/ConstantFoldingMIRBuilder.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     return;
24   // Try to use the FoldableInstructionsBuilder to build binary ops.
25   ConstantFoldingMIRBuilder 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   ConstantFoldingMIRBuilder 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     return;
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   Optional<APInt> FoldGAddInt =
84       ConstantFoldBinOp(TargetOpcode::G_ADD, MIBCst1.getReg(0),
85                         MIBCst2.getReg(0), *MRI);
86   EXPECT_TRUE(FoldGAddInt.hasValue());
87   EXPECT_EQ(25ULL, FoldGAddInt.getValue().getLimitedValue());
88   Optional<APInt> FoldGAddMix =
89       ConstantFoldBinOp(TargetOpcode::G_ADD, MIBCst1.getReg(0),
90                         MIBFCst2.getReg(0), *MRI);
91   EXPECT_TRUE(FoldGAddMix.hasValue());
92   EXPECT_EQ(1073741840ULL, FoldGAddMix.getValue().getLimitedValue());
93 
94   // Test G_AND folding Integer + Mixed Int-Float cases
95   Optional<APInt> FoldGAndInt =
96       ConstantFoldBinOp(TargetOpcode::G_AND, MIBCst1.getReg(0),
97                         MIBCst2.getReg(0), *MRI);
98   EXPECT_TRUE(FoldGAndInt.hasValue());
99   EXPECT_EQ(0ULL, FoldGAndInt.getValue().getLimitedValue());
100   Optional<APInt> FoldGAndMix =
101       ConstantFoldBinOp(TargetOpcode::G_AND, MIBCst2.getReg(0),
102                         MIBFCst1.getReg(0), *MRI);
103   EXPECT_TRUE(FoldGAndMix.hasValue());
104   EXPECT_EQ(1ULL, FoldGAndMix.getValue().getLimitedValue());
105 
106   // Test G_ASHR folding Integer + Mixed cases
107   Optional<APInt> FoldGAShrInt =
108       ConstantFoldBinOp(TargetOpcode::G_ASHR, MIBCst1.getReg(0),
109                         MIBCst2.getReg(0), *MRI);
110   EXPECT_TRUE(FoldGAShrInt.hasValue());
111   EXPECT_EQ(0ULL, FoldGAShrInt.getValue().getLimitedValue());
112   Optional<APInt> FoldGAShrMix =
113       ConstantFoldBinOp(TargetOpcode::G_ASHR, MIBFCst2.getReg(0),
114                         MIBCst2.getReg(0), *MRI);
115   EXPECT_TRUE(FoldGAShrMix.hasValue());
116   EXPECT_EQ(2097152ULL, FoldGAShrMix.getValue().getLimitedValue());
117 
118   // Test G_LSHR folding Integer + Mixed Int-Float cases
119   Optional<APInt> FoldGLShrInt =
120       ConstantFoldBinOp(TargetOpcode::G_LSHR, MIBCst1.getReg(0),
121                         MIBCst2.getReg(0), *MRI);
122   EXPECT_TRUE(FoldGLShrInt.hasValue());
123   EXPECT_EQ(0ULL, FoldGLShrInt.getValue().getLimitedValue());
124   Optional<APInt> FoldGLShrMix =
125       ConstantFoldBinOp(TargetOpcode::G_LSHR, MIBFCst1.getReg(0),
126                         MIBCst2.getReg(0), *MRI);
127   EXPECT_TRUE(FoldGLShrMix.hasValue());
128   EXPECT_EQ(2080768ULL, FoldGLShrMix.getValue().getLimitedValue());
129 
130   // Test G_MUL folding Integer + Mixed Int-Float cases
131   Optional<APInt> FoldGMulInt =
132       ConstantFoldBinOp(TargetOpcode::G_MUL, MIBCst1.getReg(0),
133                         MIBCst2.getReg(0), *MRI);
134   EXPECT_TRUE(FoldGMulInt.hasValue());
135   EXPECT_EQ(144ULL, FoldGMulInt.getValue().getLimitedValue());
136   Optional<APInt> FoldGMulMix =
137       ConstantFoldBinOp(TargetOpcode::G_MUL, MIBCst1.getReg(0),
138                         MIBFCst2.getReg(0), *MRI);
139   EXPECT_TRUE(FoldGMulMix.hasValue());
140   EXPECT_EQ(0ULL, FoldGMulMix.getValue().getLimitedValue());
141 
142   // Test G_OR folding Integer + Mixed Int-Float cases
143   Optional<APInt> FoldGOrInt =
144       ConstantFoldBinOp(TargetOpcode::G_OR, MIBCst1.getReg(0),
145                         MIBCst2.getReg(0), *MRI);
146   EXPECT_TRUE(FoldGOrInt.hasValue());
147   EXPECT_EQ(25ULL, FoldGOrInt.getValue().getLimitedValue());
148   Optional<APInt> FoldGOrMix =
149       ConstantFoldBinOp(TargetOpcode::G_OR, MIBCst1.getReg(0),
150                         MIBFCst2.getReg(0), *MRI);
151   EXPECT_TRUE(FoldGOrMix.hasValue());
152   EXPECT_EQ(1073741840ULL, FoldGOrMix.getValue().getLimitedValue());
153 
154   // Test G_SHL folding Integer + Mixed Int-Float cases
155   Optional<APInt> FoldGShlInt =
156       ConstantFoldBinOp(TargetOpcode::G_SHL, MIBCst1.getReg(0),
157                         MIBCst2.getReg(0), *MRI);
158   EXPECT_TRUE(FoldGShlInt.hasValue());
159   EXPECT_EQ(8192ULL, FoldGShlInt.getValue().getLimitedValue());
160   Optional<APInt> FoldGShlMix =
161       ConstantFoldBinOp(TargetOpcode::G_SHL, MIBCst1.getReg(0),
162                         MIBFCst2.getReg(0), *MRI);
163   EXPECT_TRUE(FoldGShlMix.hasValue());
164   EXPECT_EQ(0ULL, FoldGShlMix.getValue().getLimitedValue());
165 
166   // Test G_SUB folding Integer + Mixed Int-Float cases
167   Optional<APInt> FoldGSubInt =
168       ConstantFoldBinOp(TargetOpcode::G_SUB, MIBCst1.getReg(0),
169                         MIBCst2.getReg(0), *MRI);
170   EXPECT_TRUE(FoldGSubInt.hasValue());
171   EXPECT_EQ(7ULL, FoldGSubInt.getValue().getLimitedValue());
172   Optional<APInt> FoldGSubMix =
173       ConstantFoldBinOp(TargetOpcode::G_SUB, MIBCst1.getReg(0),
174                         MIBFCst2.getReg(0), *MRI);
175   EXPECT_TRUE(FoldGSubMix.hasValue());
176   EXPECT_EQ(3221225488ULL, FoldGSubMix.getValue().getLimitedValue());
177 
178   // Test G_XOR folding Integer + Mixed Int-Float cases
179   Optional<APInt> FoldGXorInt =
180       ConstantFoldBinOp(TargetOpcode::G_XOR, MIBCst1.getReg(0),
181                         MIBCst2.getReg(0), *MRI);
182   EXPECT_TRUE(FoldGXorInt.hasValue());
183   EXPECT_EQ(25ULL, FoldGXorInt.getValue().getLimitedValue());
184   Optional<APInt> FoldGXorMix =
185       ConstantFoldBinOp(TargetOpcode::G_XOR, MIBCst1.getReg(0),
186                         MIBFCst2.getReg(0), *MRI);
187   EXPECT_TRUE(FoldGXorMix.hasValue());
188   EXPECT_EQ(1073741840ULL, FoldGXorMix.getValue().getLimitedValue());
189 
190   // Test G_UDIV folding Integer + Mixed Int-Float cases
191   Optional<APInt> FoldGUdivInt =
192       ConstantFoldBinOp(TargetOpcode::G_UDIV, MIBCst1.getReg(0),
193                         MIBCst2.getReg(0), *MRI);
194   EXPECT_TRUE(FoldGUdivInt.hasValue());
195   EXPECT_EQ(1ULL, FoldGUdivInt.getValue().getLimitedValue());
196   Optional<APInt> FoldGUdivMix =
197       ConstantFoldBinOp(TargetOpcode::G_UDIV, MIBCst1.getReg(0),
198                         MIBFCst2.getReg(0), *MRI);
199   EXPECT_TRUE(FoldGUdivMix.hasValue());
200   EXPECT_EQ(0ULL, FoldGUdivMix.getValue().getLimitedValue());
201 
202   // Test G_SDIV folding Integer + Mixed Int-Float cases
203   Optional<APInt> FoldGSdivInt =
204       ConstantFoldBinOp(TargetOpcode::G_SDIV, MIBCst1.getReg(0),
205                         MIBCst2.getReg(0), *MRI);
206   EXPECT_TRUE(FoldGSdivInt.hasValue());
207   EXPECT_EQ(1ULL, FoldGSdivInt.getValue().getLimitedValue());
208   Optional<APInt> FoldGSdivMix =
209       ConstantFoldBinOp(TargetOpcode::G_SDIV, MIBCst1.getReg(0),
210                         MIBFCst2.getReg(0), *MRI);
211   EXPECT_TRUE(FoldGSdivMix.hasValue());
212   EXPECT_EQ(0ULL, FoldGSdivMix.getValue().getLimitedValue());
213 
214   // Test G_UREM folding Integer + Mixed Int-Float cases
215   Optional<APInt> FoldGUremInt =
216       ConstantFoldBinOp(TargetOpcode::G_UDIV, MIBCst1.getReg(0),
217                         MIBCst2.getReg(0), *MRI);
218   EXPECT_TRUE(FoldGUremInt.hasValue());
219   EXPECT_EQ(1ULL, FoldGUremInt.getValue().getLimitedValue());
220   Optional<APInt> FoldGUremMix =
221       ConstantFoldBinOp(TargetOpcode::G_UDIV, MIBCst1.getReg(0),
222                         MIBFCst2.getReg(0), *MRI);
223   EXPECT_TRUE(FoldGUremMix.hasValue());
224   EXPECT_EQ(0ULL, FoldGUremMix.getValue().getLimitedValue());
225 
226   // Test G_SREM folding Integer + Mixed Int-Float cases
227   Optional<APInt> FoldGSremInt =
228       ConstantFoldBinOp(TargetOpcode::G_SREM, MIBCst1.getReg(0),
229                         MIBCst2.getReg(0), *MRI);
230   EXPECT_TRUE(FoldGSremInt.hasValue());
231   EXPECT_EQ(7ULL, FoldGSremInt.getValue().getLimitedValue());
232   Optional<APInt> FoldGSremMix =
233       ConstantFoldBinOp(TargetOpcode::G_SREM, MIBCst1.getReg(0),
234                         MIBFCst2.getReg(0), *MRI);
235   EXPECT_TRUE(FoldGSremMix.hasValue());
236   EXPECT_EQ(16ULL, FoldGSremMix.getValue().getLimitedValue());
237 }
238 
239 } // namespace