1 //===- ConstantFoldingTest.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 "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"
20 TEST_F(AArch64GISelMITest
, FoldWithBuilder
) {
24 // Try to use the FoldableInstructionsBuilder to build binary ops.
25 CSEMIRBuilder
CFB(B
.getState());
26 LLT s32
= LLT::scalar(32);
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
));
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
));
42 // Try one of the other constructors of MachineIRBuilder to make sure it's
44 CSEMIRBuilder
CFB1(*MF
);
45 CFB1
.setInsertPt(*EntryMBB
, EntryMBB
->end());
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
));
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
));
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
));
68 EXPECT_EQ(-0x80, Cst
);
71 TEST_F(AArch64GISelMITest
, FoldBinOp
) {
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);
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());
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());
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());
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());
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());
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());
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());
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());
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());
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());
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());
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());
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());