616 changes: 616 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonStoreWidening.cpp

Large diffs are not rendered by default.

9 changes: 8 additions & 1 deletion llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ static cl::opt<bool> DisableHexagonCFGOpt("disable-hexagon-cfgopt",
cl::Hidden, cl::ZeroOrMore, cl::init(false),
cl::desc("Disable Hexagon CFG Optimization"));

static cl::opt<bool> DisableStoreWidening("disable-store-widen",
cl::Hidden, cl::init(false), cl::desc("Disable store widening"));

static cl::opt<bool> EnableExpandCondsets("hexagon-expand-condsets",
cl::init(true), cl::Hidden, cl::ZeroOrMore,
cl::desc("Early expansion of MUX"));
Expand Down Expand Up @@ -97,6 +100,7 @@ namespace llvm {
FunctionPass *createHexagonPeephole();
FunctionPass *createHexagonRemoveExtendArgs(const HexagonTargetMachine &TM);
FunctionPass *createHexagonSplitConst32AndConst64();
FunctionPass *createHexagonStoreWidening();
} // end namespace llvm;

/// HexagonTargetMachine ctor - Create an ILP32 architecture model.
Expand Down Expand Up @@ -226,9 +230,12 @@ bool HexagonPassConfig::addInstSelector() {
}

void HexagonPassConfig::addPreRegAlloc() {
if (getOptLevel() != CodeGenOpt::None)
if (getOptLevel() != CodeGenOpt::None) {
if (!DisableStoreWidening)
addPass(createHexagonStoreWidening(), false);
if (!DisableHardwareLoops)
addPass(createHexagonHardwareLoops(), false);
}
}

void HexagonPassConfig::addPostRegAlloc() {
Expand Down
21 changes: 21 additions & 0 deletions llvm/test/CodeGen/Hexagon/store-widen-aliased-load.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
; RUN: llc -march=hexagon < %s | FileCheck %s
; CHECK-NOT: memh
; Check that store widening does not merge the two stores.

target datalayout = "e-p:32:32:32-i64:64:64-i32:32:32-i16:16:16-i1:32:32-f64:64:64-f32:32:32-v64:64:64-v32:32:32-a0:0-n16:32"
target triple = "hexagon"

%struct.type_t = type { i8, i8, [2 x i8] }

define zeroext i8 @foo(%struct.type_t* nocapture %p) nounwind {
entry:
%a = getelementptr inbounds %struct.type_t, %struct.type_t* %p, i32 0, i32 0
store i8 0, i8* %a, align 2, !tbaa !0
%b = getelementptr inbounds %struct.type_t, %struct.type_t* %p, i32 0, i32 1
%0 = load i8, i8* %b, align 1, !tbaa !0
store i8 0, i8* %b, align 1, !tbaa !0
ret i8 %0
}

!0 = !{!"omnipotent char", !1}
!1 = !{!"Simple C/C++ TBAA"}
11 changes: 11 additions & 0 deletions llvm/test/CodeGen/Hexagon/store-widen-negv.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
; RUN: llc -march=hexagon < %s | FileCheck %s
; We shouldn't see a 32-bit expansion of -120, just the uint8 value.
; CHECK: #136
define i32 @foo([4 x i8]* %ptr) {
entry:
%msb = getelementptr inbounds [4 x i8], [4 x i8]* %ptr, i32 0, i32 3
%lsb = getelementptr inbounds [4 x i8], [4 x i8]* %ptr, i32 0, i32 2
store i8 0, i8* %msb
store i8 -120, i8* %lsb, align 2
ret i32 0
}
19 changes: 19 additions & 0 deletions llvm/test/CodeGen/Hexagon/store-widen-negv2.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
; RUN: llc -march=hexagon < %s | FileCheck %s
; CHECK-LABEL: foo:
; CHECK: memh(r0+#0){{.*}}={{.*}}#-2
; Don't use memh(r0+#0)=##65534.

target datalayout = "e-m:e-p:32:32-i1:32-i64:64-a:0-v32:32-n16:32"
target triple = "hexagon"

; Function Attrs: nounwind
define void @foo(i16* nocapture %s) #0 {
entry:
%0 = bitcast i16* %s to i8*
store i8 -2, i8* %0, align 2
%add.ptr = getelementptr inbounds i8, i8* %0, i32 1
store i8 -1, i8* %add.ptr, align 1
ret void
}

attributes #0 = { nounwind }
18 changes: 18 additions & 0 deletions llvm/test/CodeGen/Hexagon/store-widen.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
; RUN: llc -march=hexagon < %s | FileCheck %s
target datalayout = "e-p:32:32:32-i64:64:64-i32:32:32-i16:16:16-i1:32:32-f64:64:64-f32:32:32-v64:64:64-v32:32:32-a0:0-n16:32"
target triple = "hexagon"

define void @foo(i16* nocapture %a) nounwind {
entry:
; There should be a memw, not memh.
; CHECK: memw
; Cheated on the alignment, just to trigger the widening.
store i16 0, i16* %a, align 4, !tbaa !0
%arrayidx1 = getelementptr inbounds i16, i16* %a, i32 1
store i16 0, i16* %arrayidx1, align 2, !tbaa !0
ret void
}

!0 = !{!"short", !1}
!1 = !{!"omnipotent char", !2}
!2 = !{!"Simple C/C++ TBAA"}