Lower mem-ops to unaligned i32/i16 load/stores on ARM where supported.
authorLang Hames <lhames@gmail.com>
Tue, 8 Nov 2011 18:56:23 +0000 (18:56 +0000)
committerLang Hames <lhames@gmail.com>
Tue, 8 Nov 2011 18:56:23 +0000 (18:56 +0000)
Add support for trimming constants to GetDemandedBits. This fixes some funky
constant generation that occurs when stores are expanded for targets that don't
support unaligned stores natively.

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

lib/CodeGen/SelectionDAG/DAGCombiner.cpp
lib/Target/ARM/ARMISelLowering.cpp
test/CodeGen/ARM/2011-10-26-memset-inline.ll

index e67016ca0c740c8a476452b6a3af93fc3b78b54b..8b28ea997f493163c57aaccec9476cda9031ff10 100644 (file)
@@ -4564,6 +4564,16 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {
 SDValue DAGCombiner::GetDemandedBits(SDValue V, const APInt &Mask) {
   switch (V.getOpcode()) {
   default: break;
+  case ISD::Constant: {
+    const ConstantSDNode *CV = cast<ConstantSDNode>(V.getNode());
+    assert(CV != 0 && "Const value should be ConstSDNode.");
+    const APInt &CVal = CV->getAPIntValue();
+    APInt NewVal = CVal & Mask;
+    if (NewVal != CVal) {
+      return DAG.getConstant(NewVal, V.getValueType());
+    }
+    break;
+  }
   case ISD::OR:
   case ISD::XOR:
     // If the LHS or RHS don't contribute bits to the or, drop them.
index 84a34d587bbc3361eed400eeecddbf10d2f4705e..c51e7ae53593079d84629c26d3871f3a73de0845 100644 (file)
@@ -8171,6 +8171,13 @@ EVT ARMTargetLowering::getOptimalMemOpType(uint64_t Size,
     }
   }
 
+  // Lowering to i32/i16 if the size permits.
+  if (Size >= 4) {
+    return MVT::i32;
+  } else if (Size >= 2) {
+    return MVT::i16;
+  }
+
   // Let the target-independent logic figure it out.
   return MVT::Other;
 }
index a236ffe475c8aa4f0a7c24f4d9967a6efc09fe0e..ff049c89860df5f8e39cb0709c127c3eb5c49bcc 100644 (file)
@@ -1,14 +1,17 @@
 ; Make sure short memsets on ARM lower to stores, even when optimizing for size.
-; RUN: llc -march=arm < %s | FileCheck %s
+; RUN: llc -march=arm < %s | FileCheck %s -check-prefix=CHECK-GENERIC
+; RUN: llc -march=arm -mcpu=cortex-a8 < %s | FileCheck %s -check-prefix=CHECK-UNALIGNED
 
 target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32"
 target triple = "thumbv7-apple-ios5.0.0"
 
-; CHECK:      strb
-; CHECK-NEXT: strb
-; CHECK-NEXT: strb
-; CHECK-NEXT: strb
-; CHECK-NEXT: strb 
+; CHECK-GENERIC:      strb
+; CHECK-GENERIT-NEXT: strb
+; CHECK-GENERIT-NEXT: strb
+; CHECK-GENERIT-NEXT: strb
+; CHECK-GENERIT-NEXT: strb
+; CHECK-UNALIGNED:      strb
+; CHECK-UNALIGNED-NEXT: str 
 define void @foo(i8* nocapture %c) nounwind optsize {
 entry:
   call void @llvm.memset.p0i8.i64(i8* %c, i8 -1, i64 5, i32 1, i1 false)