diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/CodeGen/TargetLowering.h | 8 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 12 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.h | 2 | ||||
-rw-r--r-- | llvm/test/CodeGen/AArch64/arm64-memset-inline.ll | 20 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/pr38771.ll | 24 |
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 -} |