summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/CodeGen/TargetLowering.h8
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp4
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp12
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp4
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.h2
-rw-r--r--llvm/test/CodeGen/AArch64/arm64-memset-inline.ll20
-rw-r--r--llvm/test/CodeGen/X86/pr38771.ll24
7 files changed, 33 insertions, 41 deletions
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 93a08347964..585d07cf044 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -2058,6 +2058,14 @@ public:
return true;
}
+ /// Return true if the specified immediate is legal for the value input of a
+ /// store instruction.
+ virtual bool isLegalStoreImmediate(int64_t Value) const {
+ // Default implementation assumes that at least 0 works since it is likely
+ // that a zero register exists or a zero immediate is allowed.
+ return Value == 0;
+ }
+
/// Return true if it's significantly cheaper to shift a vector by a uniform
/// scalar than by an amount which will vary across each lane. On x86, for
/// example, there is a "psllw" instruction for the former case, but no simple
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index e606cbd749c..3c7830e23c7 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -15029,7 +15029,9 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
// FIXME: is there such a thing as a truncating indexed store?
if (ST->isTruncatingStore() && ST->isUnindexed() &&
- Value.getValueType().isInteger()) {
+ Value.getValueType().isInteger() &&
+ (!isa<ConstantSDNode>(Value) ||
+ !cast<ConstantSDNode>(Value)->isOpaque())) {
// See if we can simplify the input to this truncstore with knowledge that
// only the low bits are being used. For example:
// "truncstore (or (shl x, 8), y), i8" -> "truncstore y, i8"
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 1f0f7325c9d..1f63923d7ec 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -3889,9 +3889,12 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
case ISD::SIGN_EXTEND:
return getConstant(Val.sextOrTrunc(VT.getSizeInBits()), DL, VT,
C->isTargetOpcode(), C->isOpaque());
+ case ISD::TRUNCATE:
+ if (C->isOpaque())
+ break;
+ LLVM_FALLTHROUGH;
case ISD::ANY_EXTEND:
case ISD::ZERO_EXTEND:
- case ISD::TRUNCATE:
return getConstant(Val.zextOrTrunc(VT.getSizeInBits()), DL, VT,
C->isTargetOpcode(), C->isOpaque());
case ISD::UINT_TO_FP:
@@ -5158,8 +5161,11 @@ static SDValue getMemsetValue(SDValue Value, EVT VT, SelectionDAG &DAG,
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Value)) {
assert(C->getAPIntValue().getBitWidth() == 8);
APInt Val = APInt::getSplat(NumBits, C->getAPIntValue());
- if (VT.isInteger())
- return DAG.getConstant(Val, dl, VT);
+ if (VT.isInteger()) {
+ bool IsOpaque = VT.getSizeInBits() > 64 ||
+ !DAG.getTargetLoweringInfo().isLegalStoreImmediate(C->getSExtValue());
+ return DAG.getConstant(Val, dl, VT, false, IsOpaque);
+ }
return DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(VT), Val), dl,
VT);
}
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 5e4796ca54d..44d0d711dd1 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -26890,6 +26890,10 @@ bool X86TargetLowering::isLegalAddImmediate(int64_t Imm) const {
return isInt<32>(Imm);
}
+bool X86TargetLowering::isLegalStoreImmediate(int64_t Imm) const {
+ return isInt<32>(Imm);
+}
+
bool X86TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
if (!VT1.isInteger() || !VT2.isInteger())
return false;
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index 15321b12ff6..eeef7579714 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -940,6 +940,8 @@ namespace llvm {
/// the immediate into a register.
bool isLegalAddImmediate(int64_t Imm) const override;
+ bool isLegalStoreImmediate(int64_t Imm) const override;
+
/// Return the cost of the scaling factor used in the addressing
/// mode represented by AM for this target, for a load/store
/// of the specified type.
diff --git a/llvm/test/CodeGen/AArch64/arm64-memset-inline.ll b/llvm/test/CodeGen/AArch64/arm64-memset-inline.ll
index 8946d8db331..7a9f3b2fa97 100644
--- a/llvm/test/CodeGen/AArch64/arm64-memset-inline.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-memset-inline.ll
@@ -242,14 +242,12 @@ define void @memset_8_stack() {
ret void
}
-; FIXME This could be better: x9 is a superset of w8's bit-pattern.
define void @memset_12_stack() {
; CHECK-LABEL: memset_12_stack:
-; CHECK: mov w8, #-1431655766
-; CHECK-NEXT: mov x9, #-6148914691236517206
+; CHECK: mov x8, #-6148914691236517206
; CHECK-NEXT: mov x0, sp
+; CHECK-NEXT: str x8, [sp]
; CHECK-NEXT: str w8, [sp, #8]
-; CHECK-NEXT: str x9, [sp]
; CHECK-NEXT: bl something
%buf = alloca [12 x i8], align 1
%cast = bitcast [12 x i8]* %buf to i8*
@@ -272,14 +270,12 @@ define void @memset_16_stack() {
ret void
}
-; FIXME This could be better: x9 is a superset of w8's bit-pattern.
define void @memset_20_stack() {
; CHECK-LABEL: memset_20_stack:
-; CHECK: mov w8, #-1431655766
-; CHECK-NEXT: mov x9, #-6148914691236517206
+; CHECK: mov x8, #-6148914691236517206
; CHECK-NEXT: add x0, sp, #8
+; CHECK-NEXT: stp x8, x8, [sp, #8]
; CHECK-NEXT: str w8, [sp, #24]
-; CHECK-NEXT: stp x9, x9, [sp, #8]
; CHECK-NEXT: bl something
%buf = alloca [20 x i8], align 1
%cast = bitcast [20 x i8]* %buf to i8*
@@ -288,15 +284,13 @@ define void @memset_20_stack() {
ret void
}
-; FIXME This could be better: x9 is a superset of w8's bit-pattern.
define void @memset_26_stack() {
; CHECK-LABEL: memset_26_stack:
-; CHECK: mov w8, #43690
-; CHECK-NEXT: mov x9, #-6148914691236517206
+; CHECK: mov x8, #-6148914691236517206
; CHECK-NEXT: mov x0, sp
+; CHECK-NEXT: stp x8, x8, [sp, #8]
+; CHECK-NEXT: str x8, [sp]
; CHECK-NEXT: strh w8, [sp, #24]
-; CHECK-NEXT: stp x9, x9, [sp, #8]
-; CHECK-NEXT: str x9, [sp]
; CHECK-NEXT: bl something
%buf = alloca [26 x i8], align 1
%cast = bitcast [26 x i8]* %buf to i8*
diff --git a/llvm/test/CodeGen/X86/pr38771.ll b/llvm/test/CodeGen/X86/pr38771.ll
deleted file mode 100644
index 2a9ee66f7ef..00000000000
--- a/llvm/test/CodeGen/X86/pr38771.ll
+++ /dev/null
@@ -1,24 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
-
-define void @function() nounwind {
-; CHECK-LABEL: function:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: movabsq $281474976710656, %rax # imm = 0x1000000000000
-; CHECK-NEXT: notq %rax
-; CHECK-NEXT: movl $2147483647, %ecx # imm = 0x7FFFFFFF
-; CHECK-NEXT: shldq $65, %rax, %rcx
-; CHECK-NEXT: xorl %eax, %eax
-; CHECK-NEXT: movb $64, %dl
-; CHECK-NEXT: testb %dl, %dl
-; CHECK-NEXT: cmoveq %rcx, %rax
-; CHECK-NEXT: movq %rax, (%rax)
-; CHECK-NEXT: movl $0, (%rax)
-; CHECK-NEXT: retq
-entry:
- %B68 = sub i96 39614081257132168796771975167, 281474976710656
- %B49 = or i96 39614081257132168796771975167, 39614081257132168796771975167
- %B33 = lshr i96 %B68, %B68
- store i96 %B33, i96* undef
- ret void
-}
OpenPOWER on IntegriCloud