1 //===-- VEISelLowering.cpp - VE DAG Lowering Implementation ---------------===// 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 // This file implements the interfaces that VE uses to lower LLVM code into a 10 // selection DAG. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "VEISelLowering.h" 15 #include "MCTargetDesc/VEMCExpr.h" 16 #include "VEMachineFunctionInfo.h" 17 #include "VERegisterInfo.h" 18 #include "VETargetMachine.h" 19 #include "llvm/ADT/StringSwitch.h" 20 #include "llvm/CodeGen/CallingConvLower.h" 21 #include "llvm/CodeGen/MachineFrameInfo.h" 22 #include "llvm/CodeGen/MachineFunction.h" 23 #include "llvm/CodeGen/MachineInstrBuilder.h" 24 #include "llvm/CodeGen/MachineModuleInfo.h" 25 #include "llvm/CodeGen/MachineRegisterInfo.h" 26 #include "llvm/CodeGen/SelectionDAG.h" 27 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 28 #include "llvm/IR/DerivedTypes.h" 29 #include "llvm/IR/Function.h" 30 #include "llvm/IR/Module.h" 31 #include "llvm/Support/ErrorHandling.h" 32 #include "llvm/Support/KnownBits.h" 33 using namespace llvm; 34 35 #define DEBUG_TYPE "ve-lower" 36 37 //===----------------------------------------------------------------------===// 38 // Calling Convention Implementation 39 //===----------------------------------------------------------------------===// 40 41 #include "VEGenCallingConv.inc" 42 43 bool VETargetLowering::CanLowerReturn( 44 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, 45 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const { 46 CCAssignFn *RetCC = RetCC_VE; 47 SmallVector<CCValAssign, 16> RVLocs; 48 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context); 49 return CCInfo.CheckReturn(Outs, RetCC); 50 } 51 52 void VETargetLowering::initRegisterClasses() { 53 // Set up the register classes. 54 addRegisterClass(MVT::i32, &VE::I32RegClass); 55 addRegisterClass(MVT::i64, &VE::I64RegClass); 56 addRegisterClass(MVT::f32, &VE::F32RegClass); 57 addRegisterClass(MVT::f64, &VE::I64RegClass); 58 addRegisterClass(MVT::f128, &VE::F128RegClass); 59 60 addRegisterClass(MVT::v2i32, &VE::V64RegClass); 61 addRegisterClass(MVT::v4i32, &VE::V64RegClass); 62 addRegisterClass(MVT::v8i32, &VE::V64RegClass); 63 addRegisterClass(MVT::v16i32, &VE::V64RegClass); 64 addRegisterClass(MVT::v32i32, &VE::V64RegClass); 65 addRegisterClass(MVT::v64i32, &VE::V64RegClass); 66 addRegisterClass(MVT::v128i32, &VE::V64RegClass); 67 addRegisterClass(MVT::v256i32, &VE::V64RegClass); 68 addRegisterClass(MVT::v512i32, &VE::V64RegClass); 69 70 addRegisterClass(MVT::v2i64, &VE::V64RegClass); 71 addRegisterClass(MVT::v4i64, &VE::V64RegClass); 72 addRegisterClass(MVT::v8i64, &VE::V64RegClass); 73 addRegisterClass(MVT::v16i64, &VE::V64RegClass); 74 addRegisterClass(MVT::v32i64, &VE::V64RegClass); 75 addRegisterClass(MVT::v64i64, &VE::V64RegClass); 76 addRegisterClass(MVT::v128i64, &VE::V64RegClass); 77 addRegisterClass(MVT::v256i64, &VE::V64RegClass); 78 79 addRegisterClass(MVT::v2f32, &VE::V64RegClass); 80 addRegisterClass(MVT::v4f32, &VE::V64RegClass); 81 addRegisterClass(MVT::v8f32, &VE::V64RegClass); 82 addRegisterClass(MVT::v16f32, &VE::V64RegClass); 83 addRegisterClass(MVT::v32f32, &VE::V64RegClass); 84 addRegisterClass(MVT::v64f32, &VE::V64RegClass); 85 addRegisterClass(MVT::v128f32, &VE::V64RegClass); 86 addRegisterClass(MVT::v256f32, &VE::V64RegClass); 87 addRegisterClass(MVT::v512f32, &VE::V64RegClass); 88 89 addRegisterClass(MVT::v2f64, &VE::V64RegClass); 90 addRegisterClass(MVT::v4f64, &VE::V64RegClass); 91 addRegisterClass(MVT::v8f64, &VE::V64RegClass); 92 addRegisterClass(MVT::v16f64, &VE::V64RegClass); 93 addRegisterClass(MVT::v32f64, &VE::V64RegClass); 94 addRegisterClass(MVT::v64f64, &VE::V64RegClass); 95 addRegisterClass(MVT::v128f64, &VE::V64RegClass); 96 addRegisterClass(MVT::v256f64, &VE::V64RegClass); 97 98 addRegisterClass(MVT::v256i1, &VE::VMRegClass); 99 addRegisterClass(MVT::v512i1, &VE::VM512RegClass); 100 } 101 102 void VETargetLowering::initSPUActions() { 103 const auto &TM = getTargetMachine(); 104 /// Load & Store { 105 106 // VE doesn't have i1 sign extending load. 107 for (MVT VT : MVT::integer_valuetypes()) { 108 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote); 109 setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::i1, Promote); 110 setLoadExtAction(ISD::EXTLOAD, VT, MVT::i1, Promote); 111 setTruncStoreAction(VT, MVT::i1, Expand); 112 } 113 114 // VE doesn't have floating point extload/truncstore, so expand them. 115 for (MVT FPVT : MVT::fp_valuetypes()) { 116 for (MVT OtherFPVT : MVT::fp_valuetypes()) { 117 setLoadExtAction(ISD::EXTLOAD, FPVT, OtherFPVT, Expand); 118 setTruncStoreAction(FPVT, OtherFPVT, Expand); 119 } 120 } 121 122 // VE doesn't have fp128 load/store, so expand them in custom lower. 123 setOperationAction(ISD::LOAD, MVT::f128, Custom); 124 setOperationAction(ISD::STORE, MVT::f128, Custom); 125 126 /// } Load & Store 127 128 // Custom legalize address nodes into LO/HI parts. 129 MVT PtrVT = MVT::getIntegerVT(TM.getPointerSizeInBits(0)); 130 setOperationAction(ISD::BlockAddress, PtrVT, Custom); 131 setOperationAction(ISD::GlobalAddress, PtrVT, Custom); 132 setOperationAction(ISD::GlobalTLSAddress, PtrVT, Custom); 133 setOperationAction(ISD::ConstantPool, PtrVT, Custom); 134 135 /// VAARG handling { 136 setOperationAction(ISD::VASTART, MVT::Other, Custom); 137 // VAARG needs to be lowered to access with 8 bytes alignment. 138 setOperationAction(ISD::VAARG, MVT::Other, Custom); 139 // Use the default implementation. 140 setOperationAction(ISD::VACOPY, MVT::Other, Expand); 141 setOperationAction(ISD::VAEND, MVT::Other, Expand); 142 /// } VAARG handling 143 144 /// Stack { 145 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom); 146 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Custom); 147 /// } Stack 148 149 /// Branch { 150 151 // VE doesn't have BRCOND 152 setOperationAction(ISD::BRCOND, MVT::Other, Expand); 153 154 // BRIND and BR_JT are not implemented yet. 155 // FIXME: Implement both for the scalar perforamnce. 156 setOperationAction(ISD::BRIND, MVT::Other, Expand); 157 setOperationAction(ISD::BR_JT, MVT::Other, Expand); 158 159 /// } Branch 160 161 /// Int Ops { 162 for (MVT IntVT : {MVT::i32, MVT::i64}) { 163 // VE has no REM or DIVREM operations. 164 setOperationAction(ISD::UREM, IntVT, Expand); 165 setOperationAction(ISD::SREM, IntVT, Expand); 166 setOperationAction(ISD::SDIVREM, IntVT, Expand); 167 setOperationAction(ISD::UDIVREM, IntVT, Expand); 168 169 // VE has no SHL_PARTS/SRA_PARTS/SRL_PARTS operations. 170 setOperationAction(ISD::SHL_PARTS, IntVT, Expand); 171 setOperationAction(ISD::SRA_PARTS, IntVT, Expand); 172 setOperationAction(ISD::SRL_PARTS, IntVT, Expand); 173 174 // VE has no MULHU/S or U/SMUL_LOHI operations. 175 // TODO: Use MPD instruction to implement SMUL_LOHI for i32 type. 176 setOperationAction(ISD::MULHU, IntVT, Expand); 177 setOperationAction(ISD::MULHS, IntVT, Expand); 178 setOperationAction(ISD::UMUL_LOHI, IntVT, Expand); 179 setOperationAction(ISD::SMUL_LOHI, IntVT, Expand); 180 181 // VE has no CTTZ, ROTL, ROTR operations. 182 setOperationAction(ISD::CTTZ, IntVT, Expand); 183 setOperationAction(ISD::ROTL, IntVT, Expand); 184 setOperationAction(ISD::ROTR, IntVT, Expand); 185 186 // VE has 64 bits instruction which works as i64 BSWAP operation. This 187 // instruction works fine as i32 BSWAP operation with an additional 188 // parameter. Use isel patterns to lower BSWAP. 189 setOperationAction(ISD::BSWAP, IntVT, Legal); 190 191 // VE has only 64 bits instructions which work as i64 BITREVERSE/CTLZ/CTPOP 192 // operations. Use isel patterns for i64, promote for i32. 193 LegalizeAction Act = (IntVT == MVT::i32) ? Promote : Legal; 194 setOperationAction(ISD::BITREVERSE, IntVT, Act); 195 setOperationAction(ISD::CTLZ, IntVT, Act); 196 setOperationAction(ISD::CTLZ_ZERO_UNDEF, IntVT, Act); 197 setOperationAction(ISD::CTPOP, IntVT, Act); 198 199 // VE has only 64 bits instructions which work as i64 AND/OR/XOR operations. 200 // Use isel patterns for i64, promote for i32. 201 setOperationAction(ISD::AND, IntVT, Act); 202 setOperationAction(ISD::OR, IntVT, Act); 203 setOperationAction(ISD::XOR, IntVT, Act); 204 } 205 /// } Int Ops 206 207 /// Conversion { 208 // VE doesn't have instructions for fp<->uint, so expand them by llvm 209 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote); // use i64 210 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Promote); // use i64 211 setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand); 212 setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand); 213 214 // fp16 not supported 215 for (MVT FPVT : MVT::fp_valuetypes()) { 216 setOperationAction(ISD::FP16_TO_FP, FPVT, Expand); 217 setOperationAction(ISD::FP_TO_FP16, FPVT, Expand); 218 } 219 /// } Conversion 220 221 /// Floating-point Ops { 222 /// Note: Floating-point operations are fneg, fadd, fsub, fmul, fdiv, frem, 223 /// and fcmp. 224 225 // VE doesn't have following floating point operations. 226 for (MVT VT : MVT::fp_valuetypes()) { 227 setOperationAction(ISD::FNEG, VT, Expand); 228 setOperationAction(ISD::FREM, VT, Expand); 229 } 230 231 // VE doesn't have fdiv of f128. 232 setOperationAction(ISD::FDIV, MVT::f128, Expand); 233 234 for (MVT FPVT : {MVT::f32, MVT::f64}) { 235 // f32 and f64 uses ConstantFP. f128 uses ConstantPool. 236 setOperationAction(ISD::ConstantFP, FPVT, Legal); 237 } 238 /// } Floating-point Ops 239 240 /// Floating-point math functions { 241 242 // VE doesn't have following floating point math functions. 243 for (MVT VT : MVT::fp_valuetypes()) { 244 setOperationAction(ISD::FABS, VT, Expand); 245 setOperationAction(ISD::FCOPYSIGN, VT, Expand); 246 setOperationAction(ISD::FCOS, VT, Expand); 247 setOperationAction(ISD::FSIN, VT, Expand); 248 setOperationAction(ISD::FSQRT, VT, Expand); 249 } 250 251 /// } Floating-point math functions 252 253 /// Atomic instructions { 254 255 setMaxAtomicSizeInBitsSupported(64); 256 setMinCmpXchgSizeInBits(32); 257 setSupportsUnalignedAtomics(false); 258 259 // Use custom inserter for ATOMIC_FENCE. 260 setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom); 261 262 /// } Atomic isntructions 263 } 264 265 SDValue 266 VETargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, 267 bool IsVarArg, 268 const SmallVectorImpl<ISD::OutputArg> &Outs, 269 const SmallVectorImpl<SDValue> &OutVals, 270 const SDLoc &DL, SelectionDAG &DAG) const { 271 // CCValAssign - represent the assignment of the return value to locations. 272 SmallVector<CCValAssign, 16> RVLocs; 273 274 // CCState - Info about the registers and stack slot. 275 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs, 276 *DAG.getContext()); 277 278 // Analyze return values. 279 CCInfo.AnalyzeReturn(Outs, RetCC_VE); 280 281 SDValue Flag; 282 SmallVector<SDValue, 4> RetOps(1, Chain); 283 284 // Copy the result values into the output registers. 285 for (unsigned i = 0; i != RVLocs.size(); ++i) { 286 CCValAssign &VA = RVLocs[i]; 287 assert(VA.isRegLoc() && "Can only return in registers!"); 288 SDValue OutVal = OutVals[i]; 289 290 // Integer return values must be sign or zero extended by the callee. 291 switch (VA.getLocInfo()) { 292 case CCValAssign::Full: 293 break; 294 case CCValAssign::SExt: 295 OutVal = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), OutVal); 296 break; 297 case CCValAssign::ZExt: 298 OutVal = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), OutVal); 299 break; 300 case CCValAssign::AExt: 301 OutVal = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), OutVal); 302 break; 303 case CCValAssign::BCvt: { 304 // Convert a float return value to i64 with padding. 305 // 63 31 0 306 // +------+------+ 307 // | float| 0 | 308 // +------+------+ 309 assert(VA.getLocVT() == MVT::i64); 310 assert(VA.getValVT() == MVT::f32); 311 SDValue Undef = SDValue( 312 DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MVT::i64), 0); 313 SDValue Sub_f32 = DAG.getTargetConstant(VE::sub_f32, DL, MVT::i32); 314 OutVal = SDValue(DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, DL, 315 MVT::i64, Undef, OutVal, Sub_f32), 316 0); 317 break; 318 } 319 default: 320 llvm_unreachable("Unknown loc info!"); 321 } 322 323 assert(!VA.needsCustom() && "Unexpected custom lowering"); 324 325 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVal, Flag); 326 327 // Guarantee that all emitted copies are stuck together with flags. 328 Flag = Chain.getValue(1); 329 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); 330 } 331 332 RetOps[0] = Chain; // Update chain. 333 334 // Add the flag if we have it. 335 if (Flag.getNode()) 336 RetOps.push_back(Flag); 337 338 return DAG.getNode(VEISD::RET_FLAG, DL, MVT::Other, RetOps); 339 } 340 341 SDValue VETargetLowering::LowerFormalArguments( 342 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, 343 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL, 344 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { 345 MachineFunction &MF = DAG.getMachineFunction(); 346 347 // Get the base offset of the incoming arguments stack space. 348 unsigned ArgsBaseOffset = 176; 349 // Get the size of the preserved arguments area 350 unsigned ArgsPreserved = 64; 351 352 // Analyze arguments according to CC_VE. 353 SmallVector<CCValAssign, 16> ArgLocs; 354 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs, 355 *DAG.getContext()); 356 // Allocate the preserved area first. 357 CCInfo.AllocateStack(ArgsPreserved, Align(8)); 358 // We already allocated the preserved area, so the stack offset computed 359 // by CC_VE would be correct now. 360 CCInfo.AnalyzeFormalArguments(Ins, CC_VE); 361 362 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 363 CCValAssign &VA = ArgLocs[i]; 364 if (VA.isRegLoc()) { 365 // This argument is passed in a register. 366 // All integer register arguments are promoted by the caller to i64. 367 368 // Create a virtual register for the promoted live-in value. 369 unsigned VReg = 370 MF.addLiveIn(VA.getLocReg(), getRegClassFor(VA.getLocVT())); 371 SDValue Arg = DAG.getCopyFromReg(Chain, DL, VReg, VA.getLocVT()); 372 373 // Get the high bits for i32 struct elements. 374 if (VA.getValVT() == MVT::i32 && VA.needsCustom()) 375 Arg = DAG.getNode(ISD::SRL, DL, VA.getLocVT(), Arg, 376 DAG.getConstant(32, DL, MVT::i32)); 377 378 // The caller promoted the argument, so insert an Assert?ext SDNode so we 379 // won't promote the value again in this function. 380 switch (VA.getLocInfo()) { 381 case CCValAssign::SExt: 382 Arg = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), Arg, 383 DAG.getValueType(VA.getValVT())); 384 break; 385 case CCValAssign::ZExt: 386 Arg = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), Arg, 387 DAG.getValueType(VA.getValVT())); 388 break; 389 case CCValAssign::BCvt: { 390 // Extract a float argument from i64 with padding. 391 // 63 31 0 392 // +------+------+ 393 // | float| 0 | 394 // +------+------+ 395 assert(VA.getLocVT() == MVT::i64); 396 assert(VA.getValVT() == MVT::f32); 397 SDValue Sub_f32 = DAG.getTargetConstant(VE::sub_f32, DL, MVT::i32); 398 Arg = SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, 399 MVT::f32, Arg, Sub_f32), 400 0); 401 break; 402 } 403 default: 404 break; 405 } 406 407 // Truncate the register down to the argument type. 408 if (VA.isExtInLoc()) 409 Arg = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Arg); 410 411 InVals.push_back(Arg); 412 continue; 413 } 414 415 // The registers are exhausted. This argument was passed on the stack. 416 assert(VA.isMemLoc()); 417 // The CC_VE_Full/Half functions compute stack offsets relative to the 418 // beginning of the arguments area at %fp+176. 419 unsigned Offset = VA.getLocMemOffset() + ArgsBaseOffset; 420 unsigned ValSize = VA.getValVT().getSizeInBits() / 8; 421 422 // Adjust offset for a float argument by adding 4 since the argument is 423 // stored in 8 bytes buffer with offset like below. LLVM generates 424 // 4 bytes load instruction, so need to adjust offset here. This 425 // adjustment is required in only LowerFormalArguments. In LowerCall, 426 // a float argument is converted to i64 first, and stored as 8 bytes 427 // data, which is required by ABI, so no need for adjustment. 428 // 0 4 429 // +------+------+ 430 // | empty| float| 431 // +------+------+ 432 if (VA.getValVT() == MVT::f32) 433 Offset += 4; 434 435 int FI = MF.getFrameInfo().CreateFixedObject(ValSize, Offset, true); 436 InVals.push_back( 437 DAG.getLoad(VA.getValVT(), DL, Chain, 438 DAG.getFrameIndex(FI, getPointerTy(MF.getDataLayout())), 439 MachinePointerInfo::getFixedStack(MF, FI))); 440 } 441 442 if (!IsVarArg) 443 return Chain; 444 445 // This function takes variable arguments, some of which may have been passed 446 // in registers %s0-%s8. 447 // 448 // The va_start intrinsic needs to know the offset to the first variable 449 // argument. 450 // TODO: need to calculate offset correctly once we support f128. 451 unsigned ArgOffset = ArgLocs.size() * 8; 452 VEMachineFunctionInfo *FuncInfo = MF.getInfo<VEMachineFunctionInfo>(); 453 // Skip the 176 bytes of register save area. 454 FuncInfo->setVarArgsFrameOffset(ArgOffset + ArgsBaseOffset); 455 456 return Chain; 457 } 458 459 // FIXME? Maybe this could be a TableGen attribute on some registers and 460 // this table could be generated automatically from RegInfo. 461 Register VETargetLowering::getRegisterByName(const char *RegName, LLT VT, 462 const MachineFunction &MF) const { 463 Register Reg = StringSwitch<Register>(RegName) 464 .Case("sp", VE::SX11) // Stack pointer 465 .Case("fp", VE::SX9) // Frame pointer 466 .Case("sl", VE::SX8) // Stack limit 467 .Case("lr", VE::SX10) // Link register 468 .Case("tp", VE::SX14) // Thread pointer 469 .Case("outer", VE::SX12) // Outer regiser 470 .Case("info", VE::SX17) // Info area register 471 .Case("got", VE::SX15) // Global offset table register 472 .Case("plt", VE::SX16) // Procedure linkage table register 473 .Default(0); 474 475 if (Reg) 476 return Reg; 477 478 report_fatal_error("Invalid register name global variable"); 479 } 480 481 //===----------------------------------------------------------------------===// 482 // TargetLowering Implementation 483 //===----------------------------------------------------------------------===// 484 485 SDValue VETargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, 486 SmallVectorImpl<SDValue> &InVals) const { 487 SelectionDAG &DAG = CLI.DAG; 488 SDLoc DL = CLI.DL; 489 SDValue Chain = CLI.Chain; 490 auto PtrVT = getPointerTy(DAG.getDataLayout()); 491 492 // VE target does not yet support tail call optimization. 493 CLI.IsTailCall = false; 494 495 // Get the base offset of the outgoing arguments stack space. 496 unsigned ArgsBaseOffset = 176; 497 // Get the size of the preserved arguments area 498 unsigned ArgsPreserved = 8 * 8u; 499 500 // Analyze operands of the call, assigning locations to each operand. 501 SmallVector<CCValAssign, 16> ArgLocs; 502 CCState CCInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), ArgLocs, 503 *DAG.getContext()); 504 // Allocate the preserved area first. 505 CCInfo.AllocateStack(ArgsPreserved, Align(8)); 506 // We already allocated the preserved area, so the stack offset computed 507 // by CC_VE would be correct now. 508 CCInfo.AnalyzeCallOperands(CLI.Outs, CC_VE); 509 510 // VE requires to use both register and stack for varargs or no-prototyped 511 // functions. 512 bool UseBoth = CLI.IsVarArg; 513 514 // Analyze operands again if it is required to store BOTH. 515 SmallVector<CCValAssign, 16> ArgLocs2; 516 CCState CCInfo2(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), 517 ArgLocs2, *DAG.getContext()); 518 if (UseBoth) 519 CCInfo2.AnalyzeCallOperands(CLI.Outs, CC_VE2); 520 521 // Get the size of the outgoing arguments stack space requirement. 522 unsigned ArgsSize = CCInfo.getNextStackOffset(); 523 524 // Keep stack frames 16-byte aligned. 525 ArgsSize = alignTo(ArgsSize, 16); 526 527 // Adjust the stack pointer to make room for the arguments. 528 // FIXME: Use hasReservedCallFrame to avoid %sp adjustments around all calls 529 // with more than 6 arguments. 530 Chain = DAG.getCALLSEQ_START(Chain, ArgsSize, 0, DL); 531 532 // Collect the set of registers to pass to the function and their values. 533 // This will be emitted as a sequence of CopyToReg nodes glued to the call 534 // instruction. 535 SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass; 536 537 // Collect chains from all the memory opeations that copy arguments to the 538 // stack. They must follow the stack pointer adjustment above and precede the 539 // call instruction itself. 540 SmallVector<SDValue, 8> MemOpChains; 541 542 // VE needs to get address of callee function in a register 543 // So, prepare to copy it to SX12 here. 544 545 // If the callee is a GlobalAddress node (quite common, every direct call is) 546 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 547 // Likewise ExternalSymbol -> TargetExternalSymbol. 548 SDValue Callee = CLI.Callee; 549 550 bool IsPICCall = isPositionIndependent(); 551 552 // PC-relative references to external symbols should go through $stub. 553 // If so, we need to prepare GlobalBaseReg first. 554 const TargetMachine &TM = DAG.getTarget(); 555 const Module *Mod = DAG.getMachineFunction().getFunction().getParent(); 556 const GlobalValue *GV = nullptr; 557 auto *CalleeG = dyn_cast<GlobalAddressSDNode>(Callee); 558 if (CalleeG) 559 GV = CalleeG->getGlobal(); 560 bool Local = TM.shouldAssumeDSOLocal(*Mod, GV); 561 bool UsePlt = !Local; 562 MachineFunction &MF = DAG.getMachineFunction(); 563 564 // Turn GlobalAddress/ExternalSymbol node into a value node 565 // containing the address of them here. 566 if (CalleeG) { 567 if (IsPICCall) { 568 if (UsePlt) 569 Subtarget->getInstrInfo()->getGlobalBaseReg(&MF); 570 Callee = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, 0); 571 Callee = DAG.getNode(VEISD::GETFUNPLT, DL, PtrVT, Callee); 572 } else { 573 Callee = 574 makeHiLoPair(Callee, VEMCExpr::VK_VE_HI32, VEMCExpr::VK_VE_LO32, DAG); 575 } 576 } else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) { 577 if (IsPICCall) { 578 if (UsePlt) 579 Subtarget->getInstrInfo()->getGlobalBaseReg(&MF); 580 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, 0); 581 Callee = DAG.getNode(VEISD::GETFUNPLT, DL, PtrVT, Callee); 582 } else { 583 Callee = 584 makeHiLoPair(Callee, VEMCExpr::VK_VE_HI32, VEMCExpr::VK_VE_LO32, DAG); 585 } 586 } 587 588 RegsToPass.push_back(std::make_pair(VE::SX12, Callee)); 589 590 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 591 CCValAssign &VA = ArgLocs[i]; 592 SDValue Arg = CLI.OutVals[i]; 593 594 // Promote the value if needed. 595 switch (VA.getLocInfo()) { 596 default: 597 llvm_unreachable("Unknown location info!"); 598 case CCValAssign::Full: 599 break; 600 case CCValAssign::SExt: 601 Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Arg); 602 break; 603 case CCValAssign::ZExt: 604 Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Arg); 605 break; 606 case CCValAssign::AExt: 607 Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg); 608 break; 609 case CCValAssign::BCvt: { 610 // Convert a float argument to i64 with padding. 611 // 63 31 0 612 // +------+------+ 613 // | float| 0 | 614 // +------+------+ 615 assert(VA.getLocVT() == MVT::i64); 616 assert(VA.getValVT() == MVT::f32); 617 SDValue Undef = SDValue( 618 DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MVT::i64), 0); 619 SDValue Sub_f32 = DAG.getTargetConstant(VE::sub_f32, DL, MVT::i32); 620 Arg = SDValue(DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, DL, 621 MVT::i64, Undef, Arg, Sub_f32), 622 0); 623 break; 624 } 625 } 626 627 if (VA.isRegLoc()) { 628 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 629 if (!UseBoth) 630 continue; 631 VA = ArgLocs2[i]; 632 } 633 634 assert(VA.isMemLoc()); 635 636 // Create a store off the stack pointer for this argument. 637 SDValue StackPtr = DAG.getRegister(VE::SX11, PtrVT); 638 // The argument area starts at %fp+176 in the callee frame, 639 // %sp+176 in ours. 640 SDValue PtrOff = 641 DAG.getIntPtrConstant(VA.getLocMemOffset() + ArgsBaseOffset, DL); 642 PtrOff = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr, PtrOff); 643 MemOpChains.push_back( 644 DAG.getStore(Chain, DL, Arg, PtrOff, MachinePointerInfo())); 645 } 646 647 // Emit all stores, make sure they occur before the call. 648 if (!MemOpChains.empty()) 649 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains); 650 651 // Build a sequence of CopyToReg nodes glued together with token chain and 652 // glue operands which copy the outgoing args into registers. The InGlue is 653 // necessary since all emitted instructions must be stuck together in order 654 // to pass the live physical registers. 655 SDValue InGlue; 656 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 657 Chain = DAG.getCopyToReg(Chain, DL, RegsToPass[i].first, 658 RegsToPass[i].second, InGlue); 659 InGlue = Chain.getValue(1); 660 } 661 662 // Build the operands for the call instruction itself. 663 SmallVector<SDValue, 8> Ops; 664 Ops.push_back(Chain); 665 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 666 Ops.push_back(DAG.getRegister(RegsToPass[i].first, 667 RegsToPass[i].second.getValueType())); 668 669 // Add a register mask operand representing the call-preserved registers. 670 const VERegisterInfo *TRI = Subtarget->getRegisterInfo(); 671 const uint32_t *Mask = 672 TRI->getCallPreservedMask(DAG.getMachineFunction(), CLI.CallConv); 673 assert(Mask && "Missing call preserved mask for calling convention"); 674 Ops.push_back(DAG.getRegisterMask(Mask)); 675 676 // Make sure the CopyToReg nodes are glued to the call instruction which 677 // consumes the registers. 678 if (InGlue.getNode()) 679 Ops.push_back(InGlue); 680 681 // Now the call itself. 682 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 683 Chain = DAG.getNode(VEISD::CALL, DL, NodeTys, Ops); 684 InGlue = Chain.getValue(1); 685 686 // Revert the stack pointer immediately after the call. 687 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(ArgsSize, DL, true), 688 DAG.getIntPtrConstant(0, DL, true), InGlue, DL); 689 InGlue = Chain.getValue(1); 690 691 // Now extract the return values. This is more or less the same as 692 // LowerFormalArguments. 693 694 // Assign locations to each value returned by this call. 695 SmallVector<CCValAssign, 16> RVLocs; 696 CCState RVInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), RVLocs, 697 *DAG.getContext()); 698 699 // Set inreg flag manually for codegen generated library calls that 700 // return float. 701 if (CLI.Ins.size() == 1 && CLI.Ins[0].VT == MVT::f32 && !CLI.CB) 702 CLI.Ins[0].Flags.setInReg(); 703 704 RVInfo.AnalyzeCallResult(CLI.Ins, RetCC_VE); 705 706 // Copy all of the result registers out of their specified physreg. 707 for (unsigned i = 0; i != RVLocs.size(); ++i) { 708 CCValAssign &VA = RVLocs[i]; 709 unsigned Reg = VA.getLocReg(); 710 711 // When returning 'inreg {i32, i32 }', two consecutive i32 arguments can 712 // reside in the same register in the high and low bits. Reuse the 713 // CopyFromReg previous node to avoid duplicate copies. 714 SDValue RV; 715 if (RegisterSDNode *SrcReg = dyn_cast<RegisterSDNode>(Chain.getOperand(1))) 716 if (SrcReg->getReg() == Reg && Chain->getOpcode() == ISD::CopyFromReg) 717 RV = Chain.getValue(0); 718 719 // But usually we'll create a new CopyFromReg for a different register. 720 if (!RV.getNode()) { 721 RV = DAG.getCopyFromReg(Chain, DL, Reg, RVLocs[i].getLocVT(), InGlue); 722 Chain = RV.getValue(1); 723 InGlue = Chain.getValue(2); 724 } 725 726 // Get the high bits for i32 struct elements. 727 if (VA.getValVT() == MVT::i32 && VA.needsCustom()) 728 RV = DAG.getNode(ISD::SRL, DL, VA.getLocVT(), RV, 729 DAG.getConstant(32, DL, MVT::i32)); 730 731 // The callee promoted the return value, so insert an Assert?ext SDNode so 732 // we won't promote the value again in this function. 733 switch (VA.getLocInfo()) { 734 case CCValAssign::SExt: 735 RV = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), RV, 736 DAG.getValueType(VA.getValVT())); 737 break; 738 case CCValAssign::ZExt: 739 RV = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), RV, 740 DAG.getValueType(VA.getValVT())); 741 break; 742 case CCValAssign::BCvt: { 743 // Extract a float return value from i64 with padding. 744 // 63 31 0 745 // +------+------+ 746 // | float| 0 | 747 // +------+------+ 748 assert(VA.getLocVT() == MVT::i64); 749 assert(VA.getValVT() == MVT::f32); 750 SDValue Sub_f32 = DAG.getTargetConstant(VE::sub_f32, DL, MVT::i32); 751 RV = SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, 752 MVT::f32, RV, Sub_f32), 753 0); 754 break; 755 } 756 default: 757 break; 758 } 759 760 // Truncate the register down to the return value type. 761 if (VA.isExtInLoc()) 762 RV = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), RV); 763 764 InVals.push_back(RV); 765 } 766 767 return Chain; 768 } 769 770 bool VETargetLowering::isOffsetFoldingLegal( 771 const GlobalAddressSDNode *GA) const { 772 // VE uses 64 bit addressing, so we need multiple instructions to generate 773 // an address. Folding address with offset increases the number of 774 // instructions, so that we disable it here. Offsets will be folded in 775 // the DAG combine later if it worth to do so. 776 return false; 777 } 778 779 /// isFPImmLegal - Returns true if the target can instruction select the 780 /// specified FP immediate natively. If false, the legalizer will 781 /// materialize the FP immediate as a load from a constant pool. 782 bool VETargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT, 783 bool ForCodeSize) const { 784 return VT == MVT::f32 || VT == MVT::f64; 785 } 786 787 /// Determine if the target supports unaligned memory accesses. 788 /// 789 /// This function returns true if the target allows unaligned memory accesses 790 /// of the specified type in the given address space. If true, it also returns 791 /// whether the unaligned memory access is "fast" in the last argument by 792 /// reference. This is used, for example, in situations where an array 793 /// copy/move/set is converted to a sequence of store operations. Its use 794 /// helps to ensure that such replacements don't generate code that causes an 795 /// alignment error (trap) on the target machine. 796 bool VETargetLowering::allowsMisalignedMemoryAccesses(EVT VT, 797 unsigned AddrSpace, 798 unsigned Align, 799 MachineMemOperand::Flags, 800 bool *Fast) const { 801 if (Fast) { 802 // It's fast anytime on VE 803 *Fast = true; 804 } 805 return true; 806 } 807 808 bool VETargetLowering::hasAndNot(SDValue Y) const { 809 EVT VT = Y.getValueType(); 810 811 // VE doesn't have vector and not instruction. 812 if (VT.isVector()) 813 return false; 814 815 // VE allows different immediate values for X and Y where ~X & Y. 816 // Only simm7 works for X, and only mimm works for Y on VE. However, this 817 // function is used to check whether an immediate value is OK for and-not 818 // instruction as both X and Y. Generating additional instruction to 819 // retrieve an immediate value is no good since the purpose of this 820 // function is to convert a series of 3 instructions to another series of 821 // 3 instructions with better parallelism. Therefore, we return false 822 // for all immediate values now. 823 // FIXME: Change hasAndNot function to have two operands to make it work 824 // correctly with Aurora VE. 825 if (isa<ConstantSDNode>(Y)) 826 return false; 827 828 // It's ok for generic registers. 829 return true; 830 } 831 832 VETargetLowering::VETargetLowering(const TargetMachine &TM, 833 const VESubtarget &STI) 834 : TargetLowering(TM), Subtarget(&STI) { 835 // Instructions which use registers as conditionals examine all the 836 // bits (as does the pseudo SELECT_CC expansion). I don't think it 837 // matters much whether it's ZeroOrOneBooleanContent, or 838 // ZeroOrNegativeOneBooleanContent, so, arbitrarily choose the 839 // former. 840 setBooleanContents(ZeroOrOneBooleanContent); 841 setBooleanVectorContents(ZeroOrOneBooleanContent); 842 843 initRegisterClasses(); 844 initSPUActions(); 845 // TODO initVPUActions(); 846 847 setStackPointerRegisterToSaveRestore(VE::SX11); 848 849 // We have target-specific dag combine patterns for the following nodes: 850 setTargetDAGCombine(ISD::TRUNCATE); 851 852 // Set function alignment to 16 bytes 853 setMinFunctionAlignment(Align(16)); 854 855 // VE stores all argument by 8 bytes alignment 856 setMinStackArgumentAlignment(Align(8)); 857 858 computeRegisterProperties(Subtarget->getRegisterInfo()); 859 } 860 861 const char *VETargetLowering::getTargetNodeName(unsigned Opcode) const { 862 #define TARGET_NODE_CASE(NAME) \ 863 case VEISD::NAME: \ 864 return "VEISD::" #NAME; 865 switch ((VEISD::NodeType)Opcode) { 866 case VEISD::FIRST_NUMBER: 867 break; 868 TARGET_NODE_CASE(Lo) 869 TARGET_NODE_CASE(Hi) 870 TARGET_NODE_CASE(GETFUNPLT) 871 TARGET_NODE_CASE(GETSTACKTOP) 872 TARGET_NODE_CASE(GETTLSADDR) 873 TARGET_NODE_CASE(MEMBARRIER) 874 TARGET_NODE_CASE(CALL) 875 TARGET_NODE_CASE(RET_FLAG) 876 TARGET_NODE_CASE(GLOBAL_BASE_REG) 877 } 878 #undef TARGET_NODE_CASE 879 return nullptr; 880 } 881 882 EVT VETargetLowering::getSetCCResultType(const DataLayout &, LLVMContext &, 883 EVT VT) const { 884 return MVT::i32; 885 } 886 887 // Convert to a target node and set target flags. 888 SDValue VETargetLowering::withTargetFlags(SDValue Op, unsigned TF, 889 SelectionDAG &DAG) const { 890 if (const GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op)) 891 return DAG.getTargetGlobalAddress(GA->getGlobal(), SDLoc(GA), 892 GA->getValueType(0), GA->getOffset(), TF); 893 894 if (const BlockAddressSDNode *BA = dyn_cast<BlockAddressSDNode>(Op)) 895 return DAG.getTargetBlockAddress(BA->getBlockAddress(), Op.getValueType(), 896 0, TF); 897 898 if (const ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op)) 899 return DAG.getTargetConstantPool(CP->getConstVal(), CP->getValueType(0), 900 CP->getAlign(), CP->getOffset(), TF); 901 902 if (const ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Op)) 903 return DAG.getTargetExternalSymbol(ES->getSymbol(), ES->getValueType(0), 904 TF); 905 906 llvm_unreachable("Unhandled address SDNode"); 907 } 908 909 // Split Op into high and low parts according to HiTF and LoTF. 910 // Return an ADD node combining the parts. 911 SDValue VETargetLowering::makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF, 912 SelectionDAG &DAG) const { 913 SDLoc DL(Op); 914 EVT VT = Op.getValueType(); 915 SDValue Hi = DAG.getNode(VEISD::Hi, DL, VT, withTargetFlags(Op, HiTF, DAG)); 916 SDValue Lo = DAG.getNode(VEISD::Lo, DL, VT, withTargetFlags(Op, LoTF, DAG)); 917 return DAG.getNode(ISD::ADD, DL, VT, Hi, Lo); 918 } 919 920 // Build SDNodes for producing an address from a GlobalAddress, ConstantPool, 921 // or ExternalSymbol SDNode. 922 SDValue VETargetLowering::makeAddress(SDValue Op, SelectionDAG &DAG) const { 923 SDLoc DL(Op); 924 EVT PtrVT = Op.getValueType(); 925 926 // Handle PIC mode first. VE needs a got load for every variable! 927 if (isPositionIndependent()) { 928 // GLOBAL_BASE_REG codegen'ed with call. Inform MFI that this 929 // function has calls. 930 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); 931 MFI.setHasCalls(true); 932 auto GlobalN = dyn_cast<GlobalAddressSDNode>(Op); 933 934 if (isa<ConstantPoolSDNode>(Op) || 935 (GlobalN && GlobalN->getGlobal()->hasLocalLinkage())) { 936 // Create following instructions for local linkage PIC code. 937 // lea %s35, %gotoff_lo(.LCPI0_0) 938 // and %s35, %s35, (32)0 939 // lea.sl %s35, %gotoff_hi(.LCPI0_0)(%s35) 940 // adds.l %s35, %s15, %s35 ; %s15 is GOT 941 // FIXME: use lea.sl %s35, %gotoff_hi(.LCPI0_0)(%s35, %s15) 942 SDValue HiLo = makeHiLoPair(Op, VEMCExpr::VK_VE_GOTOFF_HI32, 943 VEMCExpr::VK_VE_GOTOFF_LO32, DAG); 944 SDValue GlobalBase = DAG.getNode(VEISD::GLOBAL_BASE_REG, DL, PtrVT); 945 return DAG.getNode(ISD::ADD, DL, PtrVT, GlobalBase, HiLo); 946 } 947 // Create following instructions for not local linkage PIC code. 948 // lea %s35, %got_lo(.LCPI0_0) 949 // and %s35, %s35, (32)0 950 // lea.sl %s35, %got_hi(.LCPI0_0)(%s35) 951 // adds.l %s35, %s15, %s35 ; %s15 is GOT 952 // ld %s35, (,%s35) 953 // FIXME: use lea.sl %s35, %gotoff_hi(.LCPI0_0)(%s35, %s15) 954 SDValue HiLo = makeHiLoPair(Op, VEMCExpr::VK_VE_GOT_HI32, 955 VEMCExpr::VK_VE_GOT_LO32, DAG); 956 SDValue GlobalBase = DAG.getNode(VEISD::GLOBAL_BASE_REG, DL, PtrVT); 957 SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, PtrVT, GlobalBase, HiLo); 958 return DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), AbsAddr, 959 MachinePointerInfo::getGOT(DAG.getMachineFunction())); 960 } 961 962 // This is one of the absolute code models. 963 switch (getTargetMachine().getCodeModel()) { 964 default: 965 llvm_unreachable("Unsupported absolute code model"); 966 case CodeModel::Small: 967 case CodeModel::Medium: 968 case CodeModel::Large: 969 // abs64. 970 return makeHiLoPair(Op, VEMCExpr::VK_VE_HI32, VEMCExpr::VK_VE_LO32, DAG); 971 } 972 } 973 974 /// Custom Lower { 975 976 // The mappings for emitLeading/TrailingFence for VE is designed by following 977 // http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html 978 Instruction *VETargetLowering::emitLeadingFence(IRBuilder<> &Builder, 979 Instruction *Inst, 980 AtomicOrdering Ord) const { 981 switch (Ord) { 982 case AtomicOrdering::NotAtomic: 983 case AtomicOrdering::Unordered: 984 llvm_unreachable("Invalid fence: unordered/non-atomic"); 985 case AtomicOrdering::Monotonic: 986 case AtomicOrdering::Acquire: 987 return nullptr; // Nothing to do 988 case AtomicOrdering::Release: 989 case AtomicOrdering::AcquireRelease: 990 return Builder.CreateFence(AtomicOrdering::Release); 991 case AtomicOrdering::SequentiallyConsistent: 992 if (!Inst->hasAtomicStore()) 993 return nullptr; // Nothing to do 994 return Builder.CreateFence(AtomicOrdering::SequentiallyConsistent); 995 } 996 llvm_unreachable("Unknown fence ordering in emitLeadingFence"); 997 } 998 999 Instruction *VETargetLowering::emitTrailingFence(IRBuilder<> &Builder, 1000 Instruction *Inst, 1001 AtomicOrdering Ord) const { 1002 switch (Ord) { 1003 case AtomicOrdering::NotAtomic: 1004 case AtomicOrdering::Unordered: 1005 llvm_unreachable("Invalid fence: unordered/not-atomic"); 1006 case AtomicOrdering::Monotonic: 1007 case AtomicOrdering::Release: 1008 return nullptr; // Nothing to do 1009 case AtomicOrdering::Acquire: 1010 case AtomicOrdering::AcquireRelease: 1011 return Builder.CreateFence(AtomicOrdering::Acquire); 1012 case AtomicOrdering::SequentiallyConsistent: 1013 return Builder.CreateFence(AtomicOrdering::SequentiallyConsistent); 1014 } 1015 llvm_unreachable("Unknown fence ordering in emitTrailingFence"); 1016 } 1017 1018 SDValue VETargetLowering::lowerATOMIC_FENCE(SDValue Op, 1019 SelectionDAG &DAG) const { 1020 SDLoc DL(Op); 1021 AtomicOrdering FenceOrdering = static_cast<AtomicOrdering>( 1022 cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue()); 1023 SyncScope::ID FenceSSID = static_cast<SyncScope::ID>( 1024 cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue()); 1025 1026 // VE uses Release consistency, so need a fence instruction if it is a 1027 // cross-thread fence. 1028 if (FenceSSID == SyncScope::System) { 1029 switch (FenceOrdering) { 1030 case AtomicOrdering::NotAtomic: 1031 case AtomicOrdering::Unordered: 1032 case AtomicOrdering::Monotonic: 1033 // No need to generate fencem instruction here. 1034 break; 1035 case AtomicOrdering::Acquire: 1036 // Generate "fencem 2" as acquire fence. 1037 return SDValue(DAG.getMachineNode(VE::FENCEM, DL, MVT::Other, 1038 DAG.getTargetConstant(2, DL, MVT::i32), 1039 Op.getOperand(0)), 1040 0); 1041 case AtomicOrdering::Release: 1042 // Generate "fencem 1" as release fence. 1043 return SDValue(DAG.getMachineNode(VE::FENCEM, DL, MVT::Other, 1044 DAG.getTargetConstant(1, DL, MVT::i32), 1045 Op.getOperand(0)), 1046 0); 1047 case AtomicOrdering::AcquireRelease: 1048 case AtomicOrdering::SequentiallyConsistent: 1049 // Generate "fencem 3" as acq_rel and seq_cst fence. 1050 // FIXME: "fencem 3" doesn't wait for for PCIe deveices accesses, 1051 // so seq_cst may require more instruction for them. 1052 return SDValue(DAG.getMachineNode(VE::FENCEM, DL, MVT::Other, 1053 DAG.getTargetConstant(3, DL, MVT::i32), 1054 Op.getOperand(0)), 1055 0); 1056 } 1057 } 1058 1059 // MEMBARRIER is a compiler barrier; it codegens to a no-op. 1060 return DAG.getNode(VEISD::MEMBARRIER, DL, MVT::Other, Op.getOperand(0)); 1061 } 1062 1063 SDValue VETargetLowering::lowerGlobalAddress(SDValue Op, 1064 SelectionDAG &DAG) const { 1065 return makeAddress(Op, DAG); 1066 } 1067 1068 SDValue VETargetLowering::lowerBlockAddress(SDValue Op, 1069 SelectionDAG &DAG) const { 1070 return makeAddress(Op, DAG); 1071 } 1072 1073 SDValue VETargetLowering::lowerConstantPool(SDValue Op, 1074 SelectionDAG &DAG) const { 1075 return makeAddress(Op, DAG); 1076 } 1077 1078 SDValue 1079 VETargetLowering::lowerToTLSGeneralDynamicModel(SDValue Op, 1080 SelectionDAG &DAG) const { 1081 SDLoc DL(Op); 1082 1083 // Generate the following code: 1084 // t1: ch,glue = callseq_start t0, 0, 0 1085 // t2: i64,ch,glue = VEISD::GETTLSADDR t1, label, t1:1 1086 // t3: ch,glue = callseq_end t2, 0, 0, t2:2 1087 // t4: i64,ch,glue = CopyFromReg t3, Register:i64 $sx0, t3:1 1088 SDValue Label = withTargetFlags(Op, 0, DAG); 1089 EVT PtrVT = Op.getValueType(); 1090 1091 // Lowering the machine isd will make sure everything is in the right 1092 // location. 1093 SDValue Chain = DAG.getEntryNode(); 1094 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 1095 const uint32_t *Mask = Subtarget->getRegisterInfo()->getCallPreservedMask( 1096 DAG.getMachineFunction(), CallingConv::C); 1097 Chain = DAG.getCALLSEQ_START(Chain, 64, 0, DL); 1098 SDValue Args[] = {Chain, Label, DAG.getRegisterMask(Mask), Chain.getValue(1)}; 1099 Chain = DAG.getNode(VEISD::GETTLSADDR, DL, NodeTys, Args); 1100 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(64, DL, true), 1101 DAG.getIntPtrConstant(0, DL, true), 1102 Chain.getValue(1), DL); 1103 Chain = DAG.getCopyFromReg(Chain, DL, VE::SX0, PtrVT, Chain.getValue(1)); 1104 1105 // GETTLSADDR will be codegen'ed as call. Inform MFI that function has calls. 1106 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); 1107 MFI.setHasCalls(true); 1108 1109 // Also generate code to prepare a GOT register if it is PIC. 1110 if (isPositionIndependent()) { 1111 MachineFunction &MF = DAG.getMachineFunction(); 1112 Subtarget->getInstrInfo()->getGlobalBaseReg(&MF); 1113 } 1114 1115 return Chain; 1116 } 1117 1118 SDValue VETargetLowering::lowerGlobalTLSAddress(SDValue Op, 1119 SelectionDAG &DAG) const { 1120 // The current implementation of nld (2.26) doesn't allow local exec model 1121 // code described in VE-tls_v1.1.pdf (*1) as its input. Instead, we always 1122 // generate the general dynamic model code sequence. 1123 // 1124 // *1: https://www.nec.com/en/global/prod/hpc/aurora/document/VE-tls_v1.1.pdf 1125 return lowerToTLSGeneralDynamicModel(Op, DAG); 1126 } 1127 1128 // Lower a f128 load into two f64 loads. 1129 static SDValue lowerLoadF128(SDValue Op, SelectionDAG &DAG) { 1130 SDLoc DL(Op); 1131 LoadSDNode *LdNode = dyn_cast<LoadSDNode>(Op.getNode()); 1132 assert(LdNode && LdNode->getOffset().isUndef() && "Unexpected node type"); 1133 unsigned Alignment = LdNode->getAlign().value(); 1134 if (Alignment > 8) 1135 Alignment = 8; 1136 1137 SDValue Lo64 = 1138 DAG.getLoad(MVT::f64, DL, LdNode->getChain(), LdNode->getBasePtr(), 1139 LdNode->getPointerInfo(), Alignment, 1140 LdNode->isVolatile() ? MachineMemOperand::MOVolatile 1141 : MachineMemOperand::MONone); 1142 EVT AddrVT = LdNode->getBasePtr().getValueType(); 1143 SDValue HiPtr = DAG.getNode(ISD::ADD, DL, AddrVT, LdNode->getBasePtr(), 1144 DAG.getConstant(8, DL, AddrVT)); 1145 SDValue Hi64 = 1146 DAG.getLoad(MVT::f64, DL, LdNode->getChain(), HiPtr, 1147 LdNode->getPointerInfo(), Alignment, 1148 LdNode->isVolatile() ? MachineMemOperand::MOVolatile 1149 : MachineMemOperand::MONone); 1150 1151 SDValue SubRegEven = DAG.getTargetConstant(VE::sub_even, DL, MVT::i32); 1152 SDValue SubRegOdd = DAG.getTargetConstant(VE::sub_odd, DL, MVT::i32); 1153 1154 // VE stores Hi64 to 8(addr) and Lo64 to 0(addr) 1155 SDNode *InFP128 = 1156 DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MVT::f128); 1157 InFP128 = DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, DL, MVT::f128, 1158 SDValue(InFP128, 0), Hi64, SubRegEven); 1159 InFP128 = DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, DL, MVT::f128, 1160 SDValue(InFP128, 0), Lo64, SubRegOdd); 1161 SDValue OutChains[2] = {SDValue(Lo64.getNode(), 1), 1162 SDValue(Hi64.getNode(), 1)}; 1163 SDValue OutChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains); 1164 SDValue Ops[2] = {SDValue(InFP128, 0), OutChain}; 1165 return DAG.getMergeValues(Ops, DL); 1166 } 1167 1168 SDValue VETargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const { 1169 LoadSDNode *LdNode = cast<LoadSDNode>(Op.getNode()); 1170 1171 SDValue BasePtr = LdNode->getBasePtr(); 1172 if (isa<FrameIndexSDNode>(BasePtr.getNode())) { 1173 // Do not expand store instruction with frame index here because of 1174 // dependency problems. We expand it later in eliminateFrameIndex(). 1175 return Op; 1176 } 1177 1178 EVT MemVT = LdNode->getMemoryVT(); 1179 if (MemVT == MVT::f128) 1180 return lowerLoadF128(Op, DAG); 1181 1182 return Op; 1183 } 1184 1185 // Lower a f128 store into two f64 stores. 1186 static SDValue lowerStoreF128(SDValue Op, SelectionDAG &DAG) { 1187 SDLoc DL(Op); 1188 StoreSDNode *StNode = dyn_cast<StoreSDNode>(Op.getNode()); 1189 assert(StNode && StNode->getOffset().isUndef() && "Unexpected node type"); 1190 1191 SDValue SubRegEven = DAG.getTargetConstant(VE::sub_even, DL, MVT::i32); 1192 SDValue SubRegOdd = DAG.getTargetConstant(VE::sub_odd, DL, MVT::i32); 1193 1194 SDNode *Hi64 = DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, MVT::i64, 1195 StNode->getValue(), SubRegEven); 1196 SDNode *Lo64 = DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, MVT::i64, 1197 StNode->getValue(), SubRegOdd); 1198 1199 unsigned Alignment = StNode->getAlign().value(); 1200 if (Alignment > 8) 1201 Alignment = 8; 1202 1203 // VE stores Hi64 to 8(addr) and Lo64 to 0(addr) 1204 SDValue OutChains[2]; 1205 OutChains[0] = 1206 DAG.getStore(StNode->getChain(), DL, SDValue(Lo64, 0), 1207 StNode->getBasePtr(), MachinePointerInfo(), Alignment, 1208 StNode->isVolatile() ? MachineMemOperand::MOVolatile 1209 : MachineMemOperand::MONone); 1210 EVT AddrVT = StNode->getBasePtr().getValueType(); 1211 SDValue HiPtr = DAG.getNode(ISD::ADD, DL, AddrVT, StNode->getBasePtr(), 1212 DAG.getConstant(8, DL, AddrVT)); 1213 OutChains[1] = 1214 DAG.getStore(StNode->getChain(), DL, SDValue(Hi64, 0), HiPtr, 1215 MachinePointerInfo(), Alignment, 1216 StNode->isVolatile() ? MachineMemOperand::MOVolatile 1217 : MachineMemOperand::MONone); 1218 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains); 1219 } 1220 1221 SDValue VETargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const { 1222 StoreSDNode *StNode = cast<StoreSDNode>(Op.getNode()); 1223 assert(StNode && StNode->getOffset().isUndef() && "Unexpected node type"); 1224 1225 SDValue BasePtr = StNode->getBasePtr(); 1226 if (isa<FrameIndexSDNode>(BasePtr.getNode())) { 1227 // Do not expand store instruction with frame index here because of 1228 // dependency problems. We expand it later in eliminateFrameIndex(). 1229 return Op; 1230 } 1231 1232 EVT MemVT = StNode->getMemoryVT(); 1233 if (MemVT == MVT::f128) 1234 return lowerStoreF128(Op, DAG); 1235 1236 // Otherwise, ask llvm to expand it. 1237 return SDValue(); 1238 } 1239 1240 SDValue VETargetLowering::lowerVASTART(SDValue Op, SelectionDAG &DAG) const { 1241 MachineFunction &MF = DAG.getMachineFunction(); 1242 VEMachineFunctionInfo *FuncInfo = MF.getInfo<VEMachineFunctionInfo>(); 1243 auto PtrVT = getPointerTy(DAG.getDataLayout()); 1244 1245 // Need frame address to find the address of VarArgsFrameIndex. 1246 MF.getFrameInfo().setFrameAddressIsTaken(true); 1247 1248 // vastart just stores the address of the VarArgsFrameIndex slot into the 1249 // memory location argument. 1250 SDLoc DL(Op); 1251 SDValue Offset = 1252 DAG.getNode(ISD::ADD, DL, PtrVT, DAG.getRegister(VE::SX9, PtrVT), 1253 DAG.getIntPtrConstant(FuncInfo->getVarArgsFrameOffset(), DL)); 1254 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); 1255 return DAG.getStore(Op.getOperand(0), DL, Offset, Op.getOperand(1), 1256 MachinePointerInfo(SV)); 1257 } 1258 1259 SDValue VETargetLowering::lowerVAARG(SDValue Op, SelectionDAG &DAG) const { 1260 SDNode *Node = Op.getNode(); 1261 EVT VT = Node->getValueType(0); 1262 SDValue InChain = Node->getOperand(0); 1263 SDValue VAListPtr = Node->getOperand(1); 1264 EVT PtrVT = VAListPtr.getValueType(); 1265 const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue(); 1266 SDLoc DL(Node); 1267 SDValue VAList = 1268 DAG.getLoad(PtrVT, DL, InChain, VAListPtr, MachinePointerInfo(SV)); 1269 SDValue Chain = VAList.getValue(1); 1270 SDValue NextPtr; 1271 1272 if (VT == MVT::f128) { 1273 // VE f128 values must be stored with 16 bytes alignment. We doesn't 1274 // know the actual alignment of VAList, so we take alignment of it 1275 // dyanmically. 1276 int Align = 16; 1277 VAList = DAG.getNode(ISD::ADD, DL, PtrVT, VAList, 1278 DAG.getConstant(Align - 1, DL, PtrVT)); 1279 VAList = DAG.getNode(ISD::AND, DL, PtrVT, VAList, 1280 DAG.getConstant(-Align, DL, PtrVT)); 1281 // Increment the pointer, VAList, by 16 to the next vaarg. 1282 NextPtr = 1283 DAG.getNode(ISD::ADD, DL, PtrVT, VAList, DAG.getIntPtrConstant(16, DL)); 1284 } else if (VT == MVT::f32) { 1285 // float --> need special handling like below. 1286 // 0 4 1287 // +------+------+ 1288 // | empty| float| 1289 // +------+------+ 1290 // Increment the pointer, VAList, by 8 to the next vaarg. 1291 NextPtr = 1292 DAG.getNode(ISD::ADD, DL, PtrVT, VAList, DAG.getIntPtrConstant(8, DL)); 1293 // Then, adjust VAList. 1294 unsigned InternalOffset = 4; 1295 VAList = DAG.getNode(ISD::ADD, DL, PtrVT, VAList, 1296 DAG.getConstant(InternalOffset, DL, PtrVT)); 1297 } else { 1298 // Increment the pointer, VAList, by 8 to the next vaarg. 1299 NextPtr = 1300 DAG.getNode(ISD::ADD, DL, PtrVT, VAList, DAG.getIntPtrConstant(8, DL)); 1301 } 1302 1303 // Store the incremented VAList to the legalized pointer. 1304 InChain = DAG.getStore(Chain, DL, NextPtr, VAListPtr, MachinePointerInfo(SV)); 1305 1306 // Load the actual argument out of the pointer VAList. 1307 // We can't count on greater alignment than the word size. 1308 return DAG.getLoad(VT, DL, InChain, VAList, MachinePointerInfo(), 1309 std::min(PtrVT.getSizeInBits(), VT.getSizeInBits()) / 8); 1310 } 1311 1312 SDValue VETargetLowering::lowerDYNAMIC_STACKALLOC(SDValue Op, 1313 SelectionDAG &DAG) const { 1314 // Generate following code. 1315 // (void)__llvm_grow_stack(size); 1316 // ret = GETSTACKTOP; // pseudo instruction 1317 SDLoc DL(Op); 1318 1319 // Get the inputs. 1320 SDNode *Node = Op.getNode(); 1321 SDValue Chain = Op.getOperand(0); 1322 SDValue Size = Op.getOperand(1); 1323 MaybeAlign Alignment(Op.getConstantOperandVal(2)); 1324 EVT VT = Node->getValueType(0); 1325 1326 // Chain the dynamic stack allocation so that it doesn't modify the stack 1327 // pointer when other instructions are using the stack. 1328 Chain = DAG.getCALLSEQ_START(Chain, 0, 0, DL); 1329 1330 const TargetFrameLowering &TFI = *Subtarget->getFrameLowering(); 1331 Align StackAlign = TFI.getStackAlign(); 1332 bool NeedsAlign = Alignment.valueOrOne() > StackAlign; 1333 1334 // Prepare arguments 1335 TargetLowering::ArgListTy Args; 1336 TargetLowering::ArgListEntry Entry; 1337 Entry.Node = Size; 1338 Entry.Ty = Entry.Node.getValueType().getTypeForEVT(*DAG.getContext()); 1339 Args.push_back(Entry); 1340 if (NeedsAlign) { 1341 Entry.Node = DAG.getConstant(~(Alignment->value() - 1ULL), DL, VT); 1342 Entry.Ty = Entry.Node.getValueType().getTypeForEVT(*DAG.getContext()); 1343 Args.push_back(Entry); 1344 } 1345 Type *RetTy = Type::getVoidTy(*DAG.getContext()); 1346 1347 EVT PtrVT = Op.getValueType(); 1348 SDValue Callee; 1349 if (NeedsAlign) { 1350 Callee = DAG.getTargetExternalSymbol("__ve_grow_stack_align", PtrVT, 0); 1351 } else { 1352 Callee = DAG.getTargetExternalSymbol("__ve_grow_stack", PtrVT, 0); 1353 } 1354 1355 TargetLowering::CallLoweringInfo CLI(DAG); 1356 CLI.setDebugLoc(DL) 1357 .setChain(Chain) 1358 .setCallee(CallingConv::PreserveAll, RetTy, Callee, std::move(Args)) 1359 .setDiscardResult(true); 1360 std::pair<SDValue, SDValue> pair = LowerCallTo(CLI); 1361 Chain = pair.second; 1362 SDValue Result = DAG.getNode(VEISD::GETSTACKTOP, DL, VT, Chain); 1363 if (NeedsAlign) { 1364 Result = DAG.getNode(ISD::ADD, DL, VT, Result, 1365 DAG.getConstant((Alignment->value() - 1ULL), DL, VT)); 1366 Result = DAG.getNode(ISD::AND, DL, VT, Result, 1367 DAG.getConstant(~(Alignment->value() - 1ULL), DL, VT)); 1368 } 1369 // Chain = Result.getValue(1); 1370 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(0, DL, true), 1371 DAG.getIntPtrConstant(0, DL, true), SDValue(), DL); 1372 1373 SDValue Ops[2] = {Result, Chain}; 1374 return DAG.getMergeValues(Ops, DL); 1375 } 1376 1377 SDValue VETargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { 1378 switch (Op.getOpcode()) { 1379 default: 1380 llvm_unreachable("Should not custom lower this!"); 1381 case ISD::ATOMIC_FENCE: 1382 return lowerATOMIC_FENCE(Op, DAG); 1383 case ISD::BlockAddress: 1384 return lowerBlockAddress(Op, DAG); 1385 case ISD::ConstantPool: 1386 return lowerConstantPool(Op, DAG); 1387 case ISD::DYNAMIC_STACKALLOC: 1388 return lowerDYNAMIC_STACKALLOC(Op, DAG); 1389 case ISD::GlobalAddress: 1390 return lowerGlobalAddress(Op, DAG); 1391 case ISD::GlobalTLSAddress: 1392 return lowerGlobalTLSAddress(Op, DAG); 1393 case ISD::LOAD: 1394 return lowerLOAD(Op, DAG); 1395 case ISD::STORE: 1396 return lowerSTORE(Op, DAG); 1397 case ISD::VASTART: 1398 return lowerVASTART(Op, DAG); 1399 case ISD::VAARG: 1400 return lowerVAARG(Op, DAG); 1401 } 1402 } 1403 /// } Custom Lower 1404 1405 static bool isI32Insn(const SDNode *User, const SDNode *N) { 1406 switch (User->getOpcode()) { 1407 default: 1408 return false; 1409 case ISD::ADD: 1410 case ISD::SUB: 1411 case ISD::MUL: 1412 case ISD::SDIV: 1413 case ISD::UDIV: 1414 case ISD::SETCC: 1415 case ISD::SMIN: 1416 case ISD::SMAX: 1417 case ISD::SHL: 1418 case ISD::SRA: 1419 case ISD::BSWAP: 1420 case ISD::SINT_TO_FP: 1421 case ISD::UINT_TO_FP: 1422 case ISD::BR_CC: 1423 case ISD::BITCAST: 1424 case ISD::ATOMIC_CMP_SWAP: 1425 case ISD::ATOMIC_SWAP: 1426 return true; 1427 case ISD::SRL: 1428 if (N->getOperand(0).getOpcode() != ISD::SRL) 1429 return true; 1430 // (srl (trunc (srl ...))) may be optimized by combining srl, so 1431 // doesn't optimize trunc now. 1432 return false; 1433 case ISD::SELECT_CC: 1434 if (User->getOperand(2).getNode() != N && 1435 User->getOperand(3).getNode() != N) 1436 return true; 1437 LLVM_FALLTHROUGH; 1438 case ISD::AND: 1439 case ISD::OR: 1440 case ISD::XOR: 1441 case ISD::SELECT: 1442 case ISD::CopyToReg: 1443 // Check all use of selections, bit operations, and copies. If all of them 1444 // are safe, optimize truncate to extract_subreg. 1445 for (SDNode::use_iterator UI = User->use_begin(), UE = User->use_end(); 1446 UI != UE; ++UI) { 1447 switch ((*UI)->getOpcode()) { 1448 default: 1449 // If the use is an instruction which treats the source operand as i32, 1450 // it is safe to avoid truncate here. 1451 if (isI32Insn(*UI, N)) 1452 continue; 1453 break; 1454 case ISD::ANY_EXTEND: 1455 case ISD::SIGN_EXTEND: 1456 case ISD::ZERO_EXTEND: { 1457 // Special optimizations to the combination of ext and trunc. 1458 // (ext ... (select ... (trunc ...))) is safe to avoid truncate here 1459 // since this truncate instruction clears higher 32 bits which is filled 1460 // by one of ext instructions later. 1461 assert(N->getValueType(0) == MVT::i32 && 1462 "find truncate to not i32 integer"); 1463 if (User->getOpcode() == ISD::SELECT_CC || 1464 User->getOpcode() == ISD::SELECT) 1465 continue; 1466 break; 1467 } 1468 } 1469 return false; 1470 } 1471 return true; 1472 } 1473 } 1474 1475 // Optimize TRUNCATE in DAG combining. Optimizing it in CUSTOM lower is 1476 // sometime too early. Optimizing it in DAG pattern matching in VEInstrInfo.td 1477 // is sometime too late. So, doing it at here. 1478 SDValue VETargetLowering::combineTRUNCATE(SDNode *N, 1479 DAGCombinerInfo &DCI) const { 1480 assert(N->getOpcode() == ISD::TRUNCATE && 1481 "Should be called with a TRUNCATE node"); 1482 1483 SelectionDAG &DAG = DCI.DAG; 1484 SDLoc DL(N); 1485 EVT VT = N->getValueType(0); 1486 1487 // We prefer to do this when all types are legal. 1488 if (!DCI.isAfterLegalizeDAG()) 1489 return SDValue(); 1490 1491 // Skip combine TRUNCATE atm if the operand of TRUNCATE might be a constant. 1492 if (N->getOperand(0)->getOpcode() == ISD::SELECT_CC && 1493 isa<ConstantSDNode>(N->getOperand(0)->getOperand(0)) && 1494 isa<ConstantSDNode>(N->getOperand(0)->getOperand(1))) 1495 return SDValue(); 1496 1497 // Check all use of this TRUNCATE. 1498 for (SDNode::use_iterator UI = N->use_begin(), UE = N->use_end(); UI != UE; 1499 ++UI) { 1500 SDNode *User = *UI; 1501 1502 // Make sure that we're not going to replace TRUNCATE for non i32 1503 // instructions. 1504 // 1505 // FIXME: Although we could sometimes handle this, and it does occur in 1506 // practice that one of the condition inputs to the select is also one of 1507 // the outputs, we currently can't deal with this. 1508 if (isI32Insn(User, N)) 1509 continue; 1510 1511 return SDValue(); 1512 } 1513 1514 SDValue SubI32 = DAG.getTargetConstant(VE::sub_i32, DL, MVT::i32); 1515 return SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, VT, 1516 N->getOperand(0), SubI32), 1517 0); 1518 } 1519 1520 SDValue VETargetLowering::PerformDAGCombine(SDNode *N, 1521 DAGCombinerInfo &DCI) const { 1522 switch (N->getOpcode()) { 1523 default: 1524 break; 1525 case ISD::TRUNCATE: 1526 return combineTRUNCATE(N, DCI); 1527 } 1528 1529 return SDValue(); 1530 } 1531