[CodeGenPrepare][AddressingModeMatcher] Give up on type promotion if the
authorQuentin Colombet <qcolombet@apple.com>
Fri, 14 Feb 2014 22:23:22 +0000 (22:23 +0000)
committerQuentin Colombet <qcolombet@apple.com>
Fri, 14 Feb 2014 22:23:22 +0000 (22:23 +0000)
transformation does not bring any immediate benefits and introduce an illegal
operation.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201439 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/CodeGenPrepare.cpp
test/CodeGen/R600/codegen-prepare-addrmode-sext.ll

index 0efeba4af1cb55094f63d72d82cd082a2ce64468..0fde256943d12bdc88d05099588d385fe4641952 100644 (file)
@@ -1376,6 +1376,8 @@ private:
                                             ExtAddrMode &AMBefore,
                                             ExtAddrMode &AMAfter);
   bool ValueAlreadyLiveAtInst(Value *Val, Value *KnownLive1, Value *KnownLive2);
+  bool IsPromotionProfitable(unsigned MatchedSize, unsigned SizeWithPromotion,
+                             Value *PromotedOperand) const;
 };
 
 /// MatchScaledValue - Try adding ScaleReg*Scale to the current addressing mode.
@@ -1728,6 +1730,35 @@ TypePromotionHelper::promoteOperandForOther(Instruction *SExt,
   return SExtOpnd;
 }
 
+/// IsPromotionProfitable - Check whether or not promoting an instruction
+/// to a wider type was profitable.
+/// \p MatchedSize gives the number of instructions that have been matched
+/// in the addressing mode after the promotion was applied.
+/// \p SizeWithPromotion gives the number of created instructions for
+/// the promotion plus the number of instructions that have been
+/// matched in the addressing mode before the promotion.
+/// \p PromotedOperand is the value that has been promoted.
+/// \return True if the promotion is profitable, false otherwise.
+bool
+AddressingModeMatcher::IsPromotionProfitable(unsigned MatchedSize,
+                                             unsigned SizeWithPromotion,
+                                             Value *PromotedOperand) const {
+  // We folded less instructions than what we created to promote the operand.
+  // This is not profitable.
+  if (MatchedSize < SizeWithPromotion)
+    return false;
+  if (MatchedSize > SizeWithPromotion)
+    return true;
+  // The promotion is neutral but it may help folding the sign extension in
+  // loads for instance.
+  // Check that we did not create an illegal instruction.
+  Instruction *PromotedInst = dyn_cast<Instruction>(PromotedOperand);
+  if (!PromotedInst)
+    return false;
+  return TLI.isOperationLegalOrCustom(PromotedInst->getOpcode(),
+                                      EVT::getEVT(PromotedInst->getType()));
+}
+
 /// MatchOperationAddr - Given an instruction or constant expr, see if we can
 /// fold the operation into the addressing mode.  If so, update the addressing
 /// mode and return true, otherwise return false without modifying AddrMode.
@@ -1935,9 +1966,8 @@ bool AddressingModeMatcher::MatchOperationAddr(User *AddrInst, unsigned Opcode,
     unsigned OldSize = AddrModeInsts.size();
 
     if (!MatchAddr(PromotedOperand, Depth) ||
-        // We fold less instructions than what we created.
-        // Undo at this point.
-        (OldSize + CreatedInsts > AddrModeInsts.size())) {
+        !IsPromotionProfitable(AddrModeInsts.size(), OldSize + CreatedInsts,
+                               PromotedOperand)) {
       AddrMode = BackupAddrMode;
       AddrModeInsts.resize(OldSize);
       DEBUG(dbgs() << "Sign extension does not pay off: rollback\n");
index 226f8e53737c17ace7145263dac6b406dce3aed8..6c8b26a3ae962f9cf8020b3f5701a029cdab8487 100644 (file)
@@ -3,8 +3,6 @@
 target datalayout = "e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:32:32-p5:64:64-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"
 target triple = "r600--"
 
-; XFAIL: *
-
 ; CHECK-LABEL: @test
 ; CHECK: mul
 ; CHECK-NEXT: sext