1 //===- ARMLegalizerInfo.cpp --------------------------------------*- C++ -*-==// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// \file 10 /// This file implements the targeting of the Machinelegalizer class for ARM. 11 /// \todo This should be generated by TableGen. 12 //===----------------------------------------------------------------------===// 13 14 #include "ARMLegalizerInfo.h" 15 #include "ARMCallLowering.h" 16 #include "ARMSubtarget.h" 17 #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" 18 #include "llvm/CodeGen/LowLevelType.h" 19 #include "llvm/CodeGen/MachineRegisterInfo.h" 20 #include "llvm/CodeGen/ValueTypes.h" 21 #include "llvm/IR/DerivedTypes.h" 22 #include "llvm/IR/Type.h" 23 #include "llvm/Target/TargetOpcodes.h" 24 25 using namespace llvm; 26 27 #ifndef LLVM_BUILD_GLOBAL_ISEL 28 #error "You shouldn't build this" 29 #endif 30 31 static bool AEABI(const ARMSubtarget &ST) { 32 return ST.isTargetAEABI() || ST.isTargetGNUAEABI() || ST.isTargetMuslAEABI(); 33 } 34 35 ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) { 36 using namespace TargetOpcode; 37 38 const LLT p0 = LLT::pointer(0, 32); 39 40 const LLT s1 = LLT::scalar(1); 41 const LLT s8 = LLT::scalar(8); 42 const LLT s16 = LLT::scalar(16); 43 const LLT s32 = LLT::scalar(32); 44 const LLT s64 = LLT::scalar(64); 45 46 setAction({G_GLOBAL_VALUE, p0}, Legal); 47 setAction({G_FRAME_INDEX, p0}, Legal); 48 49 for (unsigned Op : {G_LOAD, G_STORE}) { 50 for (auto Ty : {s1, s8, s16, s32, p0}) 51 setAction({Op, Ty}, Legal); 52 setAction({Op, 1, p0}, Legal); 53 } 54 55 for (unsigned Op : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) { 56 for (auto Ty : {s1, s8, s16}) 57 setAction({Op, Ty}, WidenScalar); 58 setAction({Op, s32}, Legal); 59 } 60 61 for (unsigned Op : {G_SDIV, G_UDIV}) { 62 for (auto Ty : {s8, s16}) 63 setAction({Op, Ty}, WidenScalar); 64 if (ST.hasDivideInARMMode()) 65 setAction({Op, s32}, Legal); 66 else 67 setAction({Op, s32}, Libcall); 68 } 69 70 for (unsigned Op : {G_SREM, G_UREM}) { 71 for (auto Ty : {s8, s16}) 72 setAction({Op, Ty}, WidenScalar); 73 if (ST.hasDivideInARMMode()) 74 setAction({Op, s32}, Lower); 75 else if (AEABI(ST)) 76 setAction({Op, s32}, Custom); 77 else 78 setAction({Op, s32}, Libcall); 79 } 80 81 for (unsigned Op : {G_SEXT, G_ZEXT}) { 82 setAction({Op, s32}, Legal); 83 for (auto Ty : {s1, s8, s16}) 84 setAction({Op, 1, Ty}, Legal); 85 } 86 87 setAction({G_GEP, p0}, Legal); 88 setAction({G_GEP, 1, s32}, Legal); 89 90 setAction({G_SELECT, s32}, Legal); 91 setAction({G_SELECT, p0}, Legal); 92 setAction({G_SELECT, 1, s1}, Legal); 93 94 setAction({G_BRCOND, s1}, Legal); 95 96 setAction({G_CONSTANT, s32}, Legal); 97 for (auto Ty : {s1, s8, s16}) 98 setAction({G_CONSTANT, Ty}, WidenScalar); 99 100 setAction({G_ICMP, s1}, Legal); 101 for (auto Ty : {s8, s16}) 102 setAction({G_ICMP, 1, Ty}, WidenScalar); 103 for (auto Ty : {s32, p0}) 104 setAction({G_ICMP, 1, Ty}, Legal); 105 106 if (!ST.useSoftFloat() && ST.hasVFP2()) { 107 setAction({G_FADD, s32}, Legal); 108 setAction({G_FADD, s64}, Legal); 109 110 setAction({G_LOAD, s64}, Legal); 111 setAction({G_STORE, s64}, Legal); 112 113 setAction({G_FCMP, s1}, Legal); 114 setAction({G_FCMP, 1, s32}, Legal); 115 setAction({G_FCMP, 1, s64}, Legal); 116 } else { 117 for (auto Ty : {s32, s64}) 118 setAction({G_FADD, Ty}, Libcall); 119 120 setAction({G_FCMP, s1}, Legal); 121 setAction({G_FCMP, 1, s32}, Custom); 122 setAction({G_FCMP, 1, s64}, Custom); 123 124 if (AEABI(ST)) 125 setFCmpLibcallsAEABI(); 126 else 127 setFCmpLibcallsGNU(); 128 } 129 130 for (unsigned Op : {G_FREM, G_FPOW}) 131 for (auto Ty : {s32, s64}) 132 setAction({Op, Ty}, Libcall); 133 134 computeTables(); 135 } 136 137 void ARMLegalizerInfo::setFCmpLibcallsAEABI() { 138 // FCMP_TRUE and FCMP_FALSE don't need libcalls, they should be 139 // default-initialized. 140 FCmp32Libcalls.resize(CmpInst::LAST_FCMP_PREDICATE + 1); 141 FCmp32Libcalls[CmpInst::FCMP_OEQ] = { 142 {RTLIB::OEQ_F32, CmpInst::BAD_ICMP_PREDICATE}}; 143 FCmp32Libcalls[CmpInst::FCMP_OGE] = { 144 {RTLIB::OGE_F32, CmpInst::BAD_ICMP_PREDICATE}}; 145 FCmp32Libcalls[CmpInst::FCMP_OGT] = { 146 {RTLIB::OGT_F32, CmpInst::BAD_ICMP_PREDICATE}}; 147 FCmp32Libcalls[CmpInst::FCMP_OLE] = { 148 {RTLIB::OLE_F32, CmpInst::BAD_ICMP_PREDICATE}}; 149 FCmp32Libcalls[CmpInst::FCMP_OLT] = { 150 {RTLIB::OLT_F32, CmpInst::BAD_ICMP_PREDICATE}}; 151 FCmp32Libcalls[CmpInst::FCMP_ORD] = {{RTLIB::O_F32, CmpInst::ICMP_EQ}}; 152 FCmp32Libcalls[CmpInst::FCMP_UGE] = {{RTLIB::OLT_F32, CmpInst::ICMP_EQ}}; 153 FCmp32Libcalls[CmpInst::FCMP_UGT] = {{RTLIB::OLE_F32, CmpInst::ICMP_EQ}}; 154 FCmp32Libcalls[CmpInst::FCMP_ULE] = {{RTLIB::OGT_F32, CmpInst::ICMP_EQ}}; 155 FCmp32Libcalls[CmpInst::FCMP_ULT] = {{RTLIB::OGE_F32, CmpInst::ICMP_EQ}}; 156 FCmp32Libcalls[CmpInst::FCMP_UNE] = {{RTLIB::UNE_F32, CmpInst::ICMP_EQ}}; 157 FCmp32Libcalls[CmpInst::FCMP_UNO] = { 158 {RTLIB::UO_F32, CmpInst::BAD_ICMP_PREDICATE}}; 159 FCmp32Libcalls[CmpInst::FCMP_ONE] = { 160 {RTLIB::OGT_F32, CmpInst::BAD_ICMP_PREDICATE}, 161 {RTLIB::OLT_F32, CmpInst::BAD_ICMP_PREDICATE}}; 162 FCmp32Libcalls[CmpInst::FCMP_UEQ] = { 163 {RTLIB::OEQ_F32, CmpInst::BAD_ICMP_PREDICATE}, 164 {RTLIB::UO_F32, CmpInst::BAD_ICMP_PREDICATE}}; 165 166 FCmp64Libcalls.resize(CmpInst::LAST_FCMP_PREDICATE + 1); 167 FCmp64Libcalls[CmpInst::FCMP_OEQ] = { 168 {RTLIB::OEQ_F64, CmpInst::BAD_ICMP_PREDICATE}}; 169 FCmp64Libcalls[CmpInst::FCMP_OGE] = { 170 {RTLIB::OGE_F64, CmpInst::BAD_ICMP_PREDICATE}}; 171 FCmp64Libcalls[CmpInst::FCMP_OGT] = { 172 {RTLIB::OGT_F64, CmpInst::BAD_ICMP_PREDICATE}}; 173 FCmp64Libcalls[CmpInst::FCMP_OLE] = { 174 {RTLIB::OLE_F64, CmpInst::BAD_ICMP_PREDICATE}}; 175 FCmp64Libcalls[CmpInst::FCMP_OLT] = { 176 {RTLIB::OLT_F64, CmpInst::BAD_ICMP_PREDICATE}}; 177 FCmp64Libcalls[CmpInst::FCMP_ORD] = {{RTLIB::O_F64, CmpInst::ICMP_EQ}}; 178 FCmp64Libcalls[CmpInst::FCMP_UGE] = {{RTLIB::OLT_F64, CmpInst::ICMP_EQ}}; 179 FCmp64Libcalls[CmpInst::FCMP_UGT] = {{RTLIB::OLE_F64, CmpInst::ICMP_EQ}}; 180 FCmp64Libcalls[CmpInst::FCMP_ULE] = {{RTLIB::OGT_F64, CmpInst::ICMP_EQ}}; 181 FCmp64Libcalls[CmpInst::FCMP_ULT] = {{RTLIB::OGE_F64, CmpInst::ICMP_EQ}}; 182 FCmp64Libcalls[CmpInst::FCMP_UNE] = {{RTLIB::UNE_F64, CmpInst::ICMP_EQ}}; 183 FCmp64Libcalls[CmpInst::FCMP_UNO] = { 184 {RTLIB::UO_F64, CmpInst::BAD_ICMP_PREDICATE}}; 185 FCmp64Libcalls[CmpInst::FCMP_ONE] = { 186 {RTLIB::OGT_F64, CmpInst::BAD_ICMP_PREDICATE}, 187 {RTLIB::OLT_F64, CmpInst::BAD_ICMP_PREDICATE}}; 188 FCmp64Libcalls[CmpInst::FCMP_UEQ] = { 189 {RTLIB::OEQ_F64, CmpInst::BAD_ICMP_PREDICATE}, 190 {RTLIB::UO_F64, CmpInst::BAD_ICMP_PREDICATE}}; 191 } 192 193 void ARMLegalizerInfo::setFCmpLibcallsGNU() { 194 // FCMP_TRUE and FCMP_FALSE don't need libcalls, they should be 195 // default-initialized. 196 FCmp32Libcalls.resize(CmpInst::LAST_FCMP_PREDICATE + 1); 197 FCmp32Libcalls[CmpInst::FCMP_OEQ] = {{RTLIB::OEQ_F32, CmpInst::ICMP_EQ}}; 198 FCmp32Libcalls[CmpInst::FCMP_OGE] = {{RTLIB::OGE_F32, CmpInst::ICMP_SGE}}; 199 FCmp32Libcalls[CmpInst::FCMP_OGT] = {{RTLIB::OGT_F32, CmpInst::ICMP_SGT}}; 200 FCmp32Libcalls[CmpInst::FCMP_OLE] = {{RTLIB::OLE_F32, CmpInst::ICMP_SLE}}; 201 FCmp32Libcalls[CmpInst::FCMP_OLT] = {{RTLIB::OLT_F32, CmpInst::ICMP_SLT}}; 202 FCmp32Libcalls[CmpInst::FCMP_ORD] = {{RTLIB::O_F32, CmpInst::ICMP_EQ}}; 203 FCmp32Libcalls[CmpInst::FCMP_UGE] = {{RTLIB::OLT_F32, CmpInst::ICMP_SGE}}; 204 FCmp32Libcalls[CmpInst::FCMP_UGT] = {{RTLIB::OLE_F32, CmpInst::ICMP_SGT}}; 205 FCmp32Libcalls[CmpInst::FCMP_ULE] = {{RTLIB::OGT_F32, CmpInst::ICMP_SLE}}; 206 FCmp32Libcalls[CmpInst::FCMP_ULT] = {{RTLIB::OGE_F32, CmpInst::ICMP_SLT}}; 207 FCmp32Libcalls[CmpInst::FCMP_UNE] = {{RTLIB::UNE_F32, CmpInst::ICMP_NE}}; 208 FCmp32Libcalls[CmpInst::FCMP_UNO] = {{RTLIB::UO_F32, CmpInst::ICMP_NE}}; 209 FCmp32Libcalls[CmpInst::FCMP_ONE] = {{RTLIB::OGT_F32, CmpInst::ICMP_SGT}, 210 {RTLIB::OLT_F32, CmpInst::ICMP_SLT}}; 211 FCmp32Libcalls[CmpInst::FCMP_UEQ] = {{RTLIB::OEQ_F32, CmpInst::ICMP_EQ}, 212 {RTLIB::UO_F32, CmpInst::ICMP_NE}}; 213 214 FCmp64Libcalls.resize(CmpInst::LAST_FCMP_PREDICATE + 1); 215 FCmp64Libcalls[CmpInst::FCMP_OEQ] = {{RTLIB::OEQ_F64, CmpInst::ICMP_EQ}}; 216 FCmp64Libcalls[CmpInst::FCMP_OGE] = {{RTLIB::OGE_F64, CmpInst::ICMP_SGE}}; 217 FCmp64Libcalls[CmpInst::FCMP_OGT] = {{RTLIB::OGT_F64, CmpInst::ICMP_SGT}}; 218 FCmp64Libcalls[CmpInst::FCMP_OLE] = {{RTLIB::OLE_F64, CmpInst::ICMP_SLE}}; 219 FCmp64Libcalls[CmpInst::FCMP_OLT] = {{RTLIB::OLT_F64, CmpInst::ICMP_SLT}}; 220 FCmp64Libcalls[CmpInst::FCMP_ORD] = {{RTLIB::O_F64, CmpInst::ICMP_EQ}}; 221 FCmp64Libcalls[CmpInst::FCMP_UGE] = {{RTLIB::OLT_F64, CmpInst::ICMP_SGE}}; 222 FCmp64Libcalls[CmpInst::FCMP_UGT] = {{RTLIB::OLE_F64, CmpInst::ICMP_SGT}}; 223 FCmp64Libcalls[CmpInst::FCMP_ULE] = {{RTLIB::OGT_F64, CmpInst::ICMP_SLE}}; 224 FCmp64Libcalls[CmpInst::FCMP_ULT] = {{RTLIB::OGE_F64, CmpInst::ICMP_SLT}}; 225 FCmp64Libcalls[CmpInst::FCMP_UNE] = {{RTLIB::UNE_F64, CmpInst::ICMP_NE}}; 226 FCmp64Libcalls[CmpInst::FCMP_UNO] = {{RTLIB::UO_F64, CmpInst::ICMP_NE}}; 227 FCmp64Libcalls[CmpInst::FCMP_ONE] = {{RTLIB::OGT_F64, CmpInst::ICMP_SGT}, 228 {RTLIB::OLT_F64, CmpInst::ICMP_SLT}}; 229 FCmp64Libcalls[CmpInst::FCMP_UEQ] = {{RTLIB::OEQ_F64, CmpInst::ICMP_EQ}, 230 {RTLIB::UO_F64, CmpInst::ICMP_NE}}; 231 } 232 233 ARMLegalizerInfo::FCmpLibcallsList 234 ARMLegalizerInfo::getFCmpLibcalls(CmpInst::Predicate Predicate, 235 unsigned Size) const { 236 assert(CmpInst::isFPPredicate(Predicate) && "Unsupported FCmp predicate"); 237 if (Size == 32) 238 return FCmp32Libcalls[Predicate]; 239 if (Size == 64) 240 return FCmp64Libcalls[Predicate]; 241 llvm_unreachable("Unsupported size for FCmp predicate"); 242 } 243 244 bool ARMLegalizerInfo::legalizeCustom(MachineInstr &MI, 245 MachineRegisterInfo &MRI, 246 MachineIRBuilder &MIRBuilder) const { 247 using namespace TargetOpcode; 248 249 MIRBuilder.setInstr(MI); 250 251 switch (MI.getOpcode()) { 252 default: 253 return false; 254 case G_SREM: 255 case G_UREM: { 256 unsigned OriginalResult = MI.getOperand(0).getReg(); 257 auto Size = MRI.getType(OriginalResult).getSizeInBits(); 258 if (Size != 32) 259 return false; 260 261 auto Libcall = 262 MI.getOpcode() == G_SREM ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32; 263 264 // Our divmod libcalls return a struct containing the quotient and the 265 // remainder. We need to create a virtual register for it. 266 auto &Ctx = MIRBuilder.getMF().getFunction()->getContext(); 267 Type *ArgTy = Type::getInt32Ty(Ctx); 268 StructType *RetTy = StructType::get(Ctx, {ArgTy, ArgTy}, /* Packed */ true); 269 auto RetVal = MRI.createGenericVirtualRegister( 270 getLLTForType(*RetTy, MIRBuilder.getMF().getDataLayout())); 271 272 auto Status = createLibcall(MIRBuilder, Libcall, {RetVal, RetTy}, 273 {{MI.getOperand(1).getReg(), ArgTy}, 274 {MI.getOperand(2).getReg(), ArgTy}}); 275 if (Status != LegalizerHelper::Legalized) 276 return false; 277 278 // The remainder is the second result of divmod. Split the return value into 279 // a new, unused register for the quotient and the destination of the 280 // original instruction for the remainder. 281 MIRBuilder.buildUnmerge( 282 {MRI.createGenericVirtualRegister(LLT::scalar(32)), OriginalResult}, 283 RetVal); 284 break; 285 } 286 case G_FCMP: { 287 assert(MRI.getType(MI.getOperand(2).getReg()) == 288 MRI.getType(MI.getOperand(3).getReg()) && 289 "Mismatched operands for G_FCMP"); 290 auto OpSize = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 291 292 auto OriginalResult = MI.getOperand(0).getReg(); 293 auto Predicate = 294 static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()); 295 auto Libcalls = getFCmpLibcalls(Predicate, OpSize); 296 297 if (Libcalls.empty()) { 298 assert((Predicate == CmpInst::FCMP_TRUE || 299 Predicate == CmpInst::FCMP_FALSE) && 300 "Predicate needs libcalls, but none specified"); 301 MIRBuilder.buildConstant(OriginalResult, 302 Predicate == CmpInst::FCMP_TRUE ? 1 : 0); 303 MI.eraseFromParent(); 304 return true; 305 } 306 307 auto &Ctx = MIRBuilder.getMF().getFunction()->getContext(); 308 assert((OpSize == 32 || OpSize == 64) && "Unsupported operand size"); 309 auto *ArgTy = OpSize == 32 ? Type::getFloatTy(Ctx) : Type::getDoubleTy(Ctx); 310 auto *RetTy = Type::getInt32Ty(Ctx); 311 312 SmallVector<unsigned, 2> Results; 313 for (auto Libcall : Libcalls) { 314 auto LibcallResult = MRI.createGenericVirtualRegister(LLT::scalar(32)); 315 auto Status = 316 createLibcall(MIRBuilder, Libcall.LibcallID, {LibcallResult, RetTy}, 317 {{MI.getOperand(2).getReg(), ArgTy}, 318 {MI.getOperand(3).getReg(), ArgTy}}); 319 320 if (Status != LegalizerHelper::Legalized) 321 return false; 322 323 auto ProcessedResult = 324 Libcalls.size() == 1 325 ? OriginalResult 326 : MRI.createGenericVirtualRegister(MRI.getType(OriginalResult)); 327 328 // We have a result, but we need to transform it into a proper 1-bit 0 or 329 // 1, taking into account the different peculiarities of the values 330 // returned by the comparison functions. 331 CmpInst::Predicate ResultPred = Libcall.Predicate; 332 if (ResultPred == CmpInst::BAD_ICMP_PREDICATE) { 333 // We have a nice 0 or 1, and we just need to truncate it back to 1 bit 334 // to keep the types consistent. 335 MIRBuilder.buildTrunc(ProcessedResult, LibcallResult); 336 } else { 337 // We need to compare against 0. 338 assert(CmpInst::isIntPredicate(ResultPred) && "Unsupported predicate"); 339 auto Zero = MRI.createGenericVirtualRegister(LLT::scalar(32)); 340 MIRBuilder.buildConstant(Zero, 0); 341 MIRBuilder.buildICmp(ResultPred, ProcessedResult, LibcallResult, Zero); 342 } 343 Results.push_back(ProcessedResult); 344 } 345 346 if (Results.size() != 1) { 347 assert(Results.size() == 2 && "Unexpected number of results"); 348 MIRBuilder.buildOr(OriginalResult, Results[0], Results[1]); 349 } 350 break; 351 } 352 } 353 354 MI.eraseFromParent(); 355 return true; 356 } 357