comparison lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp @ 134:3a76565eade5 LLVM5.0.1

update 5.0.1
author mir3636
date Sat, 17 Feb 2018 09:57:20 +0900
parents 803732b1fca8
children c2174574ed3a
comparison
equal deleted inserted replaced
133:c60214abe0e8 134:3a76565eade5
33 #include "llvm/CodeGen/ISDOpcodes.h" 33 #include "llvm/CodeGen/ISDOpcodes.h"
34 #include "llvm/CodeGen/MachineMemOperand.h" 34 #include "llvm/CodeGen/MachineMemOperand.h"
35 #include "llvm/CodeGen/MachineValueType.h" 35 #include "llvm/CodeGen/MachineValueType.h"
36 #include "llvm/CodeGen/SelectionDAG.h" 36 #include "llvm/CodeGen/SelectionDAG.h"
37 #include "llvm/CodeGen/SelectionDAGNodes.h" 37 #include "llvm/CodeGen/SelectionDAGNodes.h"
38 #include "llvm/CodeGen/TargetLowering.h"
38 #include "llvm/CodeGen/ValueTypes.h" 39 #include "llvm/CodeGen/ValueTypes.h"
39 #include "llvm/IR/DataLayout.h" 40 #include "llvm/IR/DataLayout.h"
40 #include "llvm/Support/Casting.h" 41 #include "llvm/Support/Casting.h"
41 #include "llvm/Support/Compiler.h" 42 #include "llvm/Support/Compiler.h"
42 #include "llvm/Support/ErrorHandling.h" 43 #include "llvm/Support/ErrorHandling.h"
43 #include "llvm/Support/MathExtras.h" 44 #include "llvm/Support/MathExtras.h"
44 #include "llvm/Target/TargetLowering.h"
45 #include <cassert> 45 #include <cassert>
46 #include <cstdint> 46 #include <cstdint>
47 #include <iterator> 47 #include <iterator>
48 #include <utility> 48 #include <utility>
49 49
50 using namespace llvm; 50 using namespace llvm;
51
52 #define DEBUG_TYPE "legalizevectorops"
51 53
52 namespace { 54 namespace {
53 55
54 class VectorLegalizer { 56 class VectorLegalizer {
55 SelectionDAG& DAG; 57 SelectionDAG& DAG;
135 /// bitcasting the result back to the original type. 137 /// bitcasting the result back to the original type.
136 SDValue Promote(SDValue Op); 138 SDValue Promote(SDValue Op);
137 139
138 /// \brief Implements [SU]INT_TO_FP vector promotion. 140 /// \brief Implements [SU]INT_TO_FP vector promotion.
139 /// 141 ///
140 /// This is a [zs]ext of the input operand to the next size up. 142 /// This is a [zs]ext of the input operand to a larger integer type.
141 SDValue PromoteINT_TO_FP(SDValue Op); 143 SDValue PromoteINT_TO_FP(SDValue Op);
142 144
143 /// \brief Implements FP_TO_[SU]INT vector promotion of the result type. 145 /// \brief Implements FP_TO_[SU]INT vector promotion of the result type.
144 /// 146 ///
145 /// It is promoted to the next size up integer type. The result is then 147 /// It is promoted to a larger integer type. The result is then
146 /// truncated back to the original type. 148 /// truncated back to the original type.
147 SDValue PromoteFP_TO_INT(SDValue Op, bool isSigned); 149 SDValue PromoteFP_TO_INT(SDValue Op);
148 150
149 public: 151 public:
150 VectorLegalizer(SelectionDAG& dag) : 152 VectorLegalizer(SelectionDAG& dag) :
151 DAG(dag), TLI(dag.getTargetLoweringInfo()) {} 153 DAG(dag), TLI(dag.getTargetLoweringInfo()) {}
152 154
224 226
225 bool HasVectorValue = false; 227 bool HasVectorValue = false;
226 if (Op.getOpcode() == ISD::LOAD) { 228 if (Op.getOpcode() == ISD::LOAD) {
227 LoadSDNode *LD = cast<LoadSDNode>(Op.getNode()); 229 LoadSDNode *LD = cast<LoadSDNode>(Op.getNode());
228 ISD::LoadExtType ExtType = LD->getExtensionType(); 230 ISD::LoadExtType ExtType = LD->getExtensionType();
229 if (LD->getMemoryVT().isVector() && ExtType != ISD::NON_EXTLOAD) 231 if (LD->getMemoryVT().isVector() && ExtType != ISD::NON_EXTLOAD) {
232 DEBUG(dbgs() << "\nLegalizing extending vector load: "; Node->dump(&DAG));
230 switch (TLI.getLoadExtAction(LD->getExtensionType(), LD->getValueType(0), 233 switch (TLI.getLoadExtAction(LD->getExtensionType(), LD->getValueType(0),
231 LD->getMemoryVT())) { 234 LD->getMemoryVT())) {
232 default: llvm_unreachable("This action is not supported yet!"); 235 default: llvm_unreachable("This action is not supported yet!");
233 case TargetLowering::Legal: 236 case TargetLowering::Legal:
234 return TranslateLegalizeResults(Op, Result); 237 return TranslateLegalizeResults(Op, Result);
250 LLVM_FALLTHROUGH; 253 LLVM_FALLTHROUGH;
251 case TargetLowering::Expand: 254 case TargetLowering::Expand:
252 Changed = true; 255 Changed = true;
253 return LegalizeOp(ExpandLoad(Op)); 256 return LegalizeOp(ExpandLoad(Op));
254 } 257 }
258 }
255 } else if (Op.getOpcode() == ISD::STORE) { 259 } else if (Op.getOpcode() == ISD::STORE) {
256 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode()); 260 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
257 EVT StVT = ST->getMemoryVT(); 261 EVT StVT = ST->getMemoryVT();
258 MVT ValVT = ST->getValue().getSimpleValueType(); 262 MVT ValVT = ST->getValue().getSimpleValueType();
259 if (StVT.isVector() && ST->isTruncatingStore()) 263 if (StVT.isVector() && ST->isTruncatingStore()) {
264 DEBUG(dbgs() << "\nLegalizing truncating vector store: ";
265 Node->dump(&DAG));
260 switch (TLI.getTruncStoreAction(ValVT, StVT)) { 266 switch (TLI.getTruncStoreAction(ValVT, StVT)) {
261 default: llvm_unreachable("This action is not supported yet!"); 267 default: llvm_unreachable("This action is not supported yet!");
262 case TargetLowering::Legal: 268 case TargetLowering::Legal:
263 return TranslateLegalizeResults(Op, Result); 269 return TranslateLegalizeResults(Op, Result);
264 case TargetLowering::Custom: { 270 case TargetLowering::Custom: {
268 } 274 }
269 case TargetLowering::Expand: 275 case TargetLowering::Expand:
270 Changed = true; 276 Changed = true;
271 return LegalizeOp(ExpandStore(Op)); 277 return LegalizeOp(ExpandStore(Op));
272 } 278 }
279 }
273 } else if (Op.getOpcode() == ISD::MSCATTER || Op.getOpcode() == ISD::MSTORE) 280 } else if (Op.getOpcode() == ISD::MSCATTER || Op.getOpcode() == ISD::MSTORE)
274 HasVectorValue = true; 281 HasVectorValue = true;
275 282
276 for (SDNode::value_iterator J = Node->value_begin(), E = Node->value_end(); 283 for (SDNode::value_iterator J = Node->value_begin(), E = Node->value_end();
277 J != E; 284 J != E;
374 case ISD::MSTORE: 381 case ISD::MSTORE:
375 QueryType = cast<MaskedStoreSDNode>(Node)->getValue().getValueType(); 382 QueryType = cast<MaskedStoreSDNode>(Node)->getValue().getValueType();
376 break; 383 break;
377 } 384 }
378 385
386 DEBUG(dbgs() << "\nLegalizing vector op: "; Node->dump(&DAG));
387
379 switch (TLI.getOperationAction(Node->getOpcode(), QueryType)) { 388 switch (TLI.getOperationAction(Node->getOpcode(), QueryType)) {
380 default: llvm_unreachable("This action is not supported yet!"); 389 default: llvm_unreachable("This action is not supported yet!");
381 case TargetLowering::Promote: 390 case TargetLowering::Promote:
382 Result = Promote(Op); 391 Result = Promote(Op);
383 Changed = true; 392 Changed = true;
384 break; 393 break;
385 case TargetLowering::Legal: 394 case TargetLowering::Legal:
395 DEBUG(dbgs() << "Legal node: nothing to do\n");
386 break; 396 break;
387 case TargetLowering::Custom: { 397 case TargetLowering::Custom: {
398 DEBUG(dbgs() << "Trying custom legalization\n");
388 if (SDValue Tmp1 = TLI.LowerOperation(Op, DAG)) { 399 if (SDValue Tmp1 = TLI.LowerOperation(Op, DAG)) {
400 DEBUG(dbgs() << "Successfully custom legalized node\n");
389 Result = Tmp1; 401 Result = Tmp1;
390 break; 402 break;
391 } 403 }
404 DEBUG(dbgs() << "Could not custom legalize node\n");
392 LLVM_FALLTHROUGH; 405 LLVM_FALLTHROUGH;
393 } 406 }
394 case TargetLowering::Expand: 407 case TargetLowering::Expand:
395 Result = Expand(Op); 408 Result = Expand(Op);
396 } 409 }
416 // "Promote" the operation by extending the operand. 429 // "Promote" the operation by extending the operand.
417 return PromoteINT_TO_FP(Op); 430 return PromoteINT_TO_FP(Op);
418 case ISD::FP_TO_UINT: 431 case ISD::FP_TO_UINT:
419 case ISD::FP_TO_SINT: 432 case ISD::FP_TO_SINT:
420 // Promote the operation by extending the operand. 433 // Promote the operation by extending the operand.
421 return PromoteFP_TO_INT(Op, Op->getOpcode() == ISD::FP_TO_SINT); 434 return PromoteFP_TO_INT(Op);
422 } 435 }
423 436
424 // There are currently two cases of vector promotion: 437 // There are currently two cases of vector promotion:
425 // 1) Bitcasting a vector of integers to a different type to a vector of the 438 // 1) Bitcasting a vector of integers to a different type to a vector of the
426 // same overall length. For example, x86 promotes ISD::AND v2i32 to v1i64. 439 // same overall length. For example, x86 promotes ISD::AND v2i32 to v1i64.
457 } 470 }
458 471
459 SDValue VectorLegalizer::PromoteINT_TO_FP(SDValue Op) { 472 SDValue VectorLegalizer::PromoteINT_TO_FP(SDValue Op) {
460 // INT_TO_FP operations may require the input operand be promoted even 473 // INT_TO_FP operations may require the input operand be promoted even
461 // when the type is otherwise legal. 474 // when the type is otherwise legal.
462 EVT VT = Op.getOperand(0).getValueType(); 475 MVT VT = Op.getOperand(0).getSimpleValueType();
463 assert(Op.getNode()->getNumValues() == 1 && 476 MVT NVT = TLI.getTypeToPromoteTo(Op.getOpcode(), VT);
464 "Can't promote a vector with multiple results!"); 477 assert(NVT.getVectorNumElements() == VT.getVectorNumElements() &&
465 478 "Vectors have different number of elements!");
466 // Normal getTypeToPromoteTo() doesn't work here, as that will promote 479
467 // by widening the vector w/ the same element width and twice the number
468 // of elements. We want the other way around, the same number of elements,
469 // each twice the width.
470 //
471 // Increase the bitwidth of the element to the next pow-of-two
472 // (which is greater than 8 bits).
473
474 EVT NVT = VT.widenIntegerVectorElementType(*DAG.getContext());
475 assert(NVT.isSimple() && "Promoting to a non-simple vector type!");
476 SDLoc dl(Op); 480 SDLoc dl(Op);
477 SmallVector<SDValue, 4> Operands(Op.getNumOperands()); 481 SmallVector<SDValue, 4> Operands(Op.getNumOperands());
478 482
479 unsigned Opc = Op.getOpcode() == ISD::UINT_TO_FP ? ISD::ZERO_EXTEND : 483 unsigned Opc = Op.getOpcode() == ISD::UINT_TO_FP ? ISD::ZERO_EXTEND :
480 ISD::SIGN_EXTEND; 484 ISD::SIGN_EXTEND;
490 494
491 // For FP_TO_INT we promote the result type to a vector type with wider 495 // For FP_TO_INT we promote the result type to a vector type with wider
492 // elements and then truncate the result. This is different from the default 496 // elements and then truncate the result. This is different from the default
493 // PromoteVector which uses bitcast to promote thus assumning that the 497 // PromoteVector which uses bitcast to promote thus assumning that the
494 // promoted vector type has the same overall size. 498 // promoted vector type has the same overall size.
495 SDValue VectorLegalizer::PromoteFP_TO_INT(SDValue Op, bool isSigned) { 499 SDValue VectorLegalizer::PromoteFP_TO_INT(SDValue Op) {
496 assert(Op.getNode()->getNumValues() == 1 && 500 MVT VT = Op.getSimpleValueType();
497 "Can't promote a vector with multiple results!"); 501 MVT NVT = TLI.getTypeToPromoteTo(Op.getOpcode(), VT);
498 EVT VT = Op.getValueType(); 502 assert(NVT.getVectorNumElements() == VT.getVectorNumElements() &&
499 503 "Vectors have different number of elements!");
500 EVT NewVT; 504
501 unsigned NewOpc; 505 unsigned NewOpc = Op->getOpcode();
502 while (true) { 506 // Change FP_TO_UINT to FP_TO_SINT if possible.
503 NewVT = VT.widenIntegerVectorElementType(*DAG.getContext()); 507 // TODO: Should we only do this if FP_TO_UINT itself isn't legal?
504 assert(NewVT.isSimple() && "Promoting to a non-simple vector type!"); 508 if (NewOpc == ISD::FP_TO_UINT &&
505 if (TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NewVT)) { 509 TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NVT))
506 NewOpc = ISD::FP_TO_SINT; 510 NewOpc = ISD::FP_TO_SINT;
507 break; 511
508 } 512 SDLoc dl(Op);
509 if (!isSigned && TLI.isOperationLegalOrCustom(ISD::FP_TO_UINT, NewVT)) { 513 SDValue Promoted = DAG.getNode(NewOpc, dl, NVT, Op.getOperand(0));
510 NewOpc = ISD::FP_TO_UINT; 514
511 break; 515 // Assert that the converted value fits in the original type. If it doesn't
512 } 516 // (eg: because the value being converted is too big), then the result of the
513 } 517 // original operation was undefined anyway, so the assert is still correct.
514 518 Promoted = DAG.getNode(Op->getOpcode() == ISD::FP_TO_UINT ? ISD::AssertZext
515 SDLoc loc(Op); 519 : ISD::AssertSext,
516 SDValue promoted = DAG.getNode(NewOpc, SDLoc(Op), NewVT, Op.getOperand(0)); 520 dl, NVT, Promoted,
517 return DAG.getNode(ISD::TRUNCATE, SDLoc(Op), VT, promoted); 521 DAG.getValueType(VT.getScalarType()));
522 return DAG.getNode(ISD::TRUNCATE, dl, VT, Promoted);
518 } 523 }
519 524
520 SDValue VectorLegalizer::ExpandLoad(SDValue Op) { 525 SDValue VectorLegalizer::ExpandLoad(SDValue Op) {
521 LoadSDNode *LD = cast<LoadSDNode>(Op.getNode()); 526 LoadSDNode *LD = cast<LoadSDNode>(Op.getNode());
522 527
552 557
553 unsigned WideBytes = WideVT.getStoreSize(); 558 unsigned WideBytes = WideVT.getStoreSize();
554 unsigned Offset = 0; 559 unsigned Offset = 0;
555 unsigned RemainingBytes = SrcVT.getStoreSize(); 560 unsigned RemainingBytes = SrcVT.getStoreSize();
556 SmallVector<SDValue, 8> LoadVals; 561 SmallVector<SDValue, 8> LoadVals;
557
558 while (RemainingBytes > 0) { 562 while (RemainingBytes > 0) {
559 SDValue ScalarLoad; 563 SDValue ScalarLoad;
560 unsigned LoadBytes = WideBytes; 564 unsigned LoadBytes = WideBytes;
561 565
562 if (RemainingBytes >= LoadBytes) { 566 if (RemainingBytes >= LoadBytes) {
578 LD->getMemOperand()->getFlags(), LD->getAAInfo()); 582 LD->getMemOperand()->getFlags(), LD->getAAInfo());
579 } 583 }
580 584
581 RemainingBytes -= LoadBytes; 585 RemainingBytes -= LoadBytes;
582 Offset += LoadBytes; 586 Offset += LoadBytes;
583 BasePTR = DAG.getNode(ISD::ADD, dl, BasePTR.getValueType(), BasePTR, 587
584 DAG.getConstant(LoadBytes, dl, 588 BasePTR = DAG.getObjectPtrOffset(dl, BasePTR, LoadBytes);
585 BasePTR.getValueType()));
586 589
587 LoadVals.push_back(ScalarLoad.getValue(0)); 590 LoadVals.push_back(ScalarLoad.getValue(0));
588 LoadChains.push_back(ScalarLoad.getValue(1)); 591 LoadChains.push_back(ScalarLoad.getValue(1));
589 } 592 }
590 593
657 return (Op.getResNo() ? NewChain : Value); 660 return (Op.getResNo() ? NewChain : Value);
658 } 661 }
659 662
660 SDValue VectorLegalizer::ExpandStore(SDValue Op) { 663 SDValue VectorLegalizer::ExpandStore(SDValue Op) {
661 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode()); 664 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
662
663 EVT StVT = ST->getMemoryVT();
664 EVT MemSclVT = StVT.getScalarType();
665 unsigned ScalarSize = MemSclVT.getSizeInBits();
666
667 // Round odd types to the next pow of two.
668 if (!isPowerOf2_32(ScalarSize)) {
669 // FIXME: This is completely broken and inconsistent with ExpandLoad
670 // handling.
671
672 // For sub-byte element sizes, this ends up with 0 stride between elements,
673 // so the same element just gets re-written to the same location. There seem
674 // to be tests explicitly testing for this broken behavior though. tests
675 // for this broken behavior.
676
677 LLVMContext &Ctx = *DAG.getContext();
678
679 EVT NewMemVT
680 = EVT::getVectorVT(Ctx,
681 MemSclVT.getIntegerVT(Ctx, NextPowerOf2(ScalarSize)),
682 StVT.getVectorNumElements());
683
684 SDValue NewVectorStore = DAG.getTruncStore(
685 ST->getChain(), SDLoc(Op), ST->getValue(), ST->getBasePtr(),
686 ST->getPointerInfo(), NewMemVT, ST->getAlignment(),
687 ST->getMemOperand()->getFlags(), ST->getAAInfo());
688 ST = cast<StoreSDNode>(NewVectorStore.getNode());
689 }
690
691 SDValue TF = TLI.scalarizeVectorStore(ST, DAG); 665 SDValue TF = TLI.scalarizeVectorStore(ST, DAG);
692 AddLegalizedOperand(Op, TF); 666 AddLegalizedOperand(Op, TF);
693 return TF; 667 return TF;
694 } 668 }
695 669