-; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s
+; RUN: llc -march=hexagon -hexagon-small-data-threshold=0 < %s | FileCheck %s
; Check that we generate load instructions with absolute addressing mode.
-@a = external global i32
-@b = external global i8
-@c = external global i16
+@a0 = external global i32
+@a1 = external global i32
+@b0 = external global i8
+@b1 = external global i8
+@c0 = external global i16
+@c1 = external global i16
@d = external global i64
define zeroext i8 @absStoreByte() nounwind {
-; CHECK: memb(##b){{ *}}={{ *}}r{{[0-9]+}}
+; CHECK: memb(##b1){{ *}}={{ *}}r{{[0-9]+}}
entry:
- %0 = load i8, i8* @b, align 1
+ %0 = load i8, i8* @b0, align 1
%conv = zext i8 %0 to i32
%mul = mul nsw i32 100, %conv
%conv1 = trunc i32 %mul to i8
- store i8 %conv1, i8* @b, align 1
+ store i8 %conv1, i8* @b1, align 1
ret i8 %conv1
}
define signext i16 @absStoreHalf() nounwind {
-; CHECK: memh(##c){{ *}}={{ *}}r{{[0-9]+}}
+; CHECK: memh(##c1){{ *}}={{ *}}r{{[0-9]+}}
entry:
- %0 = load i16, i16* @c, align 2
+ %0 = load i16, i16* @c0, align 2
%conv = sext i16 %0 to i32
%mul = mul nsw i32 100, %conv
%conv1 = trunc i32 %mul to i16
- store i16 %conv1, i16* @c, align 2
+ store i16 %conv1, i16* @c1, align 2
ret i16 %conv1
}
define i32 @absStoreWord() nounwind {
-; CHECK: memw(##a){{ *}}={{ *}}r{{[0-9]+}}
+; CHECK: memw(##a1){{ *}}={{ *}}r{{[0-9]+}}
entry:
- %0 = load i32, i32* @a, align 4
+ %0 = load i32, i32* @a0, align 4
%mul = mul nsw i32 100, %0
- store i32 %mul, i32* @a, align 4
+ store i32 %mul, i32* @a1, align 4
ret i32 %mul
}
-; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s
+; RUN: llc -march=hexagon < %s | FileCheck %s
; Check that we generate absolute addressing mode instructions
; with immediate value.
--- /dev/null
+; RUN: llc -march=hexagon < %s | FileCheck %s
+; CHECK: r{{[0-9]+}} = add(r{{[0-9]+}}.{{L|l}}, r{{[0-9]+}}.{{H|h}})
+
+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-unknown-none"
+
+%struct.aDataType = type { i16, i16, i16, i16, i16, i16*, i16*, i16*, i8*, i16*, i16*, i16*, i8* }
+
+define i8* @a_get_score(%struct.aDataType* nocapture %pData, i16 signext %gmmModelIndex, i16* nocapture %pGmmScoreL16Q4) #0 {
+entry:
+ %numSubVector = getelementptr inbounds %struct.aDataType, %struct.aDataType* %pData, i32 0, i32 3
+ %0 = load i16, i16* %numSubVector, align 2, !tbaa !0
+ %and = and i16 %0, -4
+ %b = getelementptr inbounds %struct.aDataType, %struct.aDataType* %pData, i32 0, i32 8
+ %1 = load i8*, i8** %b, align 4, !tbaa !3
+ %conv3 = sext i16 %and to i32
+ %cmp21 = icmp sgt i16 %and, 0
+ br i1 %cmp21, label %for.inc.preheader, label %for.end
+
+for.inc.preheader: ; preds = %entry
+ br label %for.inc
+
+for.inc: ; preds = %for.inc.preheader, %for.inc
+ %j.022 = phi i32 [ %phitmp, %for.inc ], [ 0, %for.inc.preheader ]
+ %add13 = mul i32 %j.022, 65536
+ %sext = add i32 %add13, 262144
+ %phitmp = ashr exact i32 %sext, 16
+ %cmp = icmp slt i32 %phitmp, %conv3
+ br i1 %cmp, label %for.inc, label %for.end.loopexit
+
+for.end.loopexit: ; preds = %for.inc
+ br label %for.end
+
+for.end: ; preds = %for.end.loopexit, %entry
+ ret i8* %1
+}
+
+attributes #0 = { nounwind readonly "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!0 = !{!"short", !1}
+!1 = !{!"omnipotent char", !2}
+!2 = !{!"Simple C/C++ TBAA"}
+!3 = !{!"any pointer", !1}
--- /dev/null
+; RUN: llc -march=hexagon < %s | FileCheck %s
+; CHECK: r{{[0-9]+}} = add(r{{[0-9]+}}.{{L|l}}, r{{[0-9]+}}.{{L|l}}):<<16
+
+define i64 @test_cast(i64 %arg0, i16 zeroext %arg1, i16 zeroext %arg2) nounwind readnone {
+entry:
+ %conv.i = zext i16 %arg1 to i32
+ %conv1.i = zext i16 %arg2 to i32
+ %sub.i = add nsw i32 %conv.i, %conv1.i
+ %sext.i = shl i32 %sub.i, 16
+ %cmp.i = icmp slt i32 %sext.i, 65536
+ %0 = ashr exact i32 %sext.i, 16
+ %conv7.i = select i1 %cmp.i, i32 1, i32 %0
+ %cmp8.i = icmp sgt i32 %conv7.i, 4
+ %conv7.op.i = add i32 %conv7.i, 65535
+ %shl = shl i64 %arg0, 2
+ %.mask = and i32 %conv7.op.i, 65535
+ %1 = zext i32 %.mask to i64
+ %conv = select i1 %cmp8.i, i64 3, i64 %1
+ %or = or i64 %conv, %shl
+ ret i64 %or
+}
--- /dev/null
+; RUN: llc -march=hexagon < %s | FileCheck %s
+; CHECK: r{{[0-9]+}} = add(r{{[0-9]+}}.{{L|l}}, r{{[0-9]+}}.{{L|l}})
+
+define i64 @test_cast(i64 %arg0, i16 zeroext %arg1, i16 zeroext %arg2) nounwind readnone {
+entry:
+ %conv.i = zext i16 %arg1 to i32
+ %conv1.i = zext i16 %arg2 to i32
+ %sub.i = add nsw i32 %conv.i, %conv1.i
+ %sext.i = shl i32 %sub.i, 16
+ %cmp.i = icmp slt i32 %sext.i, 65536
+ %0 = ashr exact i32 %sext.i, 16
+ %conv7.i = select i1 %cmp.i, i32 1, i32 %0
+ %cmp8.i = icmp sgt i32 %conv7.i, 4
+ %conv7.op.i = add i32 %conv7.i, 65535
+ %shl = shl i64 %arg0, 2
+ %.mask = and i32 %conv7.op.i, 65535
+ %1 = zext i32 %.mask to i64
+ %conv = select i1 %cmp8.i, i64 3, i64 %1
+ %or = or i64 %conv, %shl
+ ret i64 %or
+}
--- /dev/null
+; RUN: llc -march=hexagon < %s | FileCheck %s
+;
+; Bug 6840. Use absolute+index addressing.
+
+@ga = common global [1024 x i8] zeroinitializer, align 8
+@gb = common global [1024 x i8] zeroinitializer, align 8
+
+; CHECK: memub(r{{[0-9]+}}{{ *}}<<{{ *}}#0{{ *}}+{{ *}}##ga)
+define zeroext i8 @lf2(i32 %i) nounwind readonly {
+entry:
+ %arrayidx = getelementptr inbounds [1024 x i8], [1024 x i8]* @ga, i32 0, i32 %i
+ %0 = load i8, i8* %arrayidx, align 1
+ ret i8 %0
+}
+
+; CHECK: memb(r{{[0-9]+}}{{ *}}<<{{ *}}#0{{ *}}+{{ *}}##gb)
+define signext i8 @lf2s(i32 %i) nounwind readonly {
+entry:
+ %arrayidx = getelementptr inbounds [1024 x i8], [1024 x i8]* @gb, i32 0, i32 %i
+ %0 = load i8, i8* %arrayidx, align 1
+ ret i8 %0
+}
+
+; CHECK: memub(r{{[0-9]+}}{{ *}}<<{{ *}}#2{{ *}}+{{ *}}##ga)
+define zeroext i8 @lf3(i32 %i) nounwind readonly {
+entry:
+ %mul = shl nsw i32 %i, 2
+ %arrayidx = getelementptr inbounds [1024 x i8], [1024 x i8]* @ga, i32 0, i32 %mul
+ %0 = load i8, i8* %arrayidx, align 1
+ ret i8 %0
+}
+
+; CHECK: memb(r{{[0-9]+}}{{ *}}<<{{ *}}#2{{ *}}+{{ *}}##gb)
+define signext i8 @lf3s(i32 %i) nounwind readonly {
+entry:
+ %mul = shl nsw i32 %i, 2
+ %arrayidx = getelementptr inbounds [1024 x i8], [1024 x i8]* @gb, i32 0, i32 %mul
+ %0 = load i8, i8* %arrayidx, align 1
+ ret i8 %0
+}
+
+; CHECK: memb(r{{[0-9]+}}{{ *}}<<{{ *}}#0{{ *}}+{{ *}}##ga)
+define void @sf4(i32 %i, i8 zeroext %j) nounwind {
+entry:
+ %arrayidx = getelementptr inbounds [1024 x i8], [1024 x i8]* @ga, i32 0, i32 %i
+ store i8 %j, i8* %arrayidx, align 1
+ ret void
+}
+
+; CHECK: memb(r{{[0-9]+}}{{ *}}<<{{ *}}#0{{ *}}+{{ *}}##gb)
+define void @sf4s(i32 %i, i8 signext %j) nounwind {
+entry:
+ %arrayidx = getelementptr inbounds [1024 x i8], [1024 x i8]* @gb, i32 0, i32 %i
+ store i8 %j, i8* %arrayidx, align 1
+ ret void
+}
+
+; CHECK: memb(r{{[0-9]+}}{{ *}}<<{{ *}}#2{{ *}}+{{ *}}##ga)
+define void @sf5(i32 %i, i8 zeroext %j) nounwind {
+entry:
+ %mul = shl nsw i32 %i, 2
+ %arrayidx = getelementptr inbounds [1024 x i8], [1024 x i8]* @ga, i32 0, i32 %mul
+ store i8 %j, i8* %arrayidx, align 1
+ ret void
+}
+
+; CHECK: memb(r{{[0-9]+}}{{ *}}<<{{ *}}#2{{ *}}+{{ *}}##gb)
+define void @sf5s(i32 %i, i8 signext %j) nounwind {
+entry:
+ %mul = shl nsw i32 %i, 2
+ %arrayidx = getelementptr inbounds [1024 x i8], [1024 x i8]* @gb, i32 0, i32 %mul
+ store i8 %j, i8* %arrayidx, align 1
+ ret void
+}
-; XFAIL:
-; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s
+; RUN: llc -march=hexagon < %s | FileCheck %s
; Check that we don't generate an invalid packet with too many instructions
; due to a store that has a must-extend operand.
; CHECK: CuSuiteAdd.exit.us
-; CHECK: {
; CHECK-NOT: call abort
; CHECK: memw(##0)
-; CHECK: memw(r{{[0-9+]}}<<#2 + ##4)
-; CHECK: }
+; CHECK: memw(r{{[0-9+]}}{{ *}}<<{{ *}}#2{{ *}}+{{ *}}##4)
%struct.CuTest.1.28.31.37.40.43.52.55.67.85.111 = type { i8*, void (%struct.CuTest.1.28.31.37.40.43.52.55.67.85.111*)*, i32, i32, i8*, [23 x i32]* }
%struct.CuSuite.2.29.32.38.41.44.53.56.68.86.112 = type { i32, [1024 x %struct.CuTest.1.28.31.37.40.43.52.55.67.85.111*], i32 }
; CHECK: r5:4 = combine(#6, #5)
; CHECK: r3:2 = combine(#4, #3)
; CHECK: r1:0 = combine(#2, #1)
-; CHECK: memw(r29{{ *}}+{{ *}}#0){{ *}}={{ *}}#7
+; CHECK: memw(r29+#0)=#7
define void @foo() nounwind {
-; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s
+; RUN: llc -march=hexagon < %s | FileCheck %s
define i32 @foo(i32 %a, i32 %b) nounwind readnone {
; CHECK: lsl
--- /dev/null
+; RUN: llc -O2 < %s
+; Check for successful compilation. It originally caused an abort due to
+; the "isBarrier" flag set on instructions that were not meant to have it.
+
+target datalayout = "e-m:e-p:32:32-i1:32-i64:64-a:0-v32:32-n16:32"
+target triple = "hexagon"
+
+; Function Attrs: nounwind optsize readnone
+define void @dummy() #0 {
+entry:
+ ret void
+}
+
+; Function Attrs: nounwind optsize
+define void @conv3x3(i8* nocapture readonly %inp, i8* nocapture readonly %mask, i32 %shift, i8* nocapture %outp, i32 %width) #1 {
+entry:
+ %cmp381 = icmp sgt i32 %width, 0
+ %arrayidx16.gep = getelementptr i8, i8* %mask, i32 4
+ %arrayidx19.gep = getelementptr i8, i8* %mask, i32 8
+ br label %for.body
+
+for.body: ; preds = %for.inc48, %entry
+ %i.086 = phi i32 [ 0, %entry ], [ %inc49, %for.inc48 ]
+ %mul = mul nsw i32 %i.086, %width
+ %arrayidx.sum = add i32 %mul, %width
+ br i1 %cmp381, label %for.cond5.preheader.lr.ph, label %for.inc48
+
+for.cond5.preheader.lr.ph: ; preds = %for.body
+ %add.ptr.sum = add i32 %arrayidx.sum, %width
+ %add.ptr1 = getelementptr inbounds i8, i8* %inp, i32 %add.ptr.sum
+ %add.ptr = getelementptr inbounds i8, i8* %inp, i32 %arrayidx.sum
+ %arrayidx = getelementptr inbounds i8, i8* %inp, i32 %mul
+ %arrayidx44.gep = getelementptr i8, i8* %outp, i32 %mul
+ br label %for.cond5.preheader
+
+for.cond5.preheader: ; preds = %if.end40, %for.cond5.preheader.lr.ph
+ %arrayidx44.phi = phi i8* [ %arrayidx44.gep, %for.cond5.preheader.lr.ph ], [ %arrayidx44.inc, %if.end40 ]
+ %j.085 = phi i32 [ 0, %for.cond5.preheader.lr.ph ], [ %inc46, %if.end40 ]
+ %IN1.084 = phi i8* [ %arrayidx, %for.cond5.preheader.lr.ph ], [ %incdec.ptr, %if.end40 ]
+ %IN2.083 = phi i8* [ %add.ptr, %for.cond5.preheader.lr.ph ], [ %incdec.ptr33, %if.end40 ]
+ %IN3.082 = phi i8* [ %add.ptr1, %for.cond5.preheader.lr.ph ], [ %incdec.ptr34, %if.end40 ]
+ br label %for.body7
+
+for.body7: ; preds = %for.body7, %for.cond5.preheader
+ %arrayidx8.phi = phi i8* [ %IN1.084, %for.cond5.preheader ], [ %arrayidx8.inc, %for.body7 ]
+ %arrayidx9.phi = phi i8* [ %IN2.083, %for.cond5.preheader ], [ %arrayidx9.inc, %for.body7 ]
+ %arrayidx11.phi = phi i8* [ %IN3.082, %for.cond5.preheader ], [ %arrayidx11.inc, %for.body7 ]
+ %arrayidx13.phi = phi i8* [ %mask, %for.cond5.preheader ], [ %arrayidx13.inc, %for.body7 ]
+ %arrayidx16.phi = phi i8* [ %arrayidx16.gep, %for.cond5.preheader ], [ %arrayidx16.inc, %for.body7 ]
+ %arrayidx19.phi = phi i8* [ %arrayidx19.gep, %for.cond5.preheader ], [ %arrayidx19.inc, %for.body7 ]
+ %k.080 = phi i32 [ 0, %for.cond5.preheader ], [ %inc, %for.body7 ]
+ %sum.079 = phi i32 [ 0, %for.cond5.preheader ], [ %add32, %for.body7 ]
+ %0 = load i8, i8* %arrayidx8.phi, align 1, !tbaa !1
+ %1 = load i8, i8* %arrayidx9.phi, align 1, !tbaa !1
+ %2 = load i8, i8* %arrayidx11.phi, align 1, !tbaa !1
+ %3 = load i8, i8* %arrayidx13.phi, align 1, !tbaa !1
+ %4 = load i8, i8* %arrayidx16.phi, align 1, !tbaa !1
+ %5 = load i8, i8* %arrayidx19.phi, align 1, !tbaa !1
+ %conv21 = zext i8 %0 to i32
+ %conv22 = sext i8 %3 to i32
+ %mul23 = mul nsw i32 %conv22, %conv21
+ %conv24 = zext i8 %1 to i32
+ %conv25 = sext i8 %4 to i32
+ %mul26 = mul nsw i32 %conv25, %conv24
+ %conv27 = zext i8 %2 to i32
+ %conv28 = sext i8 %5 to i32
+ %mul29 = mul nsw i32 %conv28, %conv27
+ %add30 = add i32 %mul23, %sum.079
+ %add31 = add i32 %add30, %mul26
+ %add32 = add i32 %add31, %mul29
+ %inc = add nsw i32 %k.080, 1
+ %exitcond = icmp eq i32 %inc, 3
+ %arrayidx8.inc = getelementptr i8, i8* %arrayidx8.phi, i32 1
+ %arrayidx9.inc = getelementptr i8, i8* %arrayidx9.phi, i32 1
+ %arrayidx11.inc = getelementptr i8, i8* %arrayidx11.phi, i32 1
+ %arrayidx13.inc = getelementptr i8, i8* %arrayidx13.phi, i32 1
+ %arrayidx16.inc = getelementptr i8, i8* %arrayidx16.phi, i32 1
+ %arrayidx19.inc = getelementptr i8, i8* %arrayidx19.phi, i32 1
+ br i1 %exitcond, label %for.end, label %for.body7
+
+for.end: ; preds = %for.body7
+ %incdec.ptr = getelementptr inbounds i8, i8* %IN1.084, i32 1
+ %incdec.ptr33 = getelementptr inbounds i8, i8* %IN2.083, i32 1
+ %incdec.ptr34 = getelementptr inbounds i8, i8* %IN3.082, i32 1
+ %shr = ashr i32 %add32, %shift
+ %cmp35 = icmp slt i32 %shr, 0
+ br i1 %cmp35, label %if.end40, label %if.end
+
+if.end: ; preds = %for.end
+ %cmp37 = icmp sgt i32 %shr, 255
+ br i1 %cmp37, label %if.then39, label %if.end40
+
+if.then39: ; preds = %if.end
+ br label %if.end40
+
+if.end40: ; preds = %for.end, %if.then39, %if.end
+ %sum.2 = phi i32 [ 255, %if.then39 ], [ %shr, %if.end ], [ 0, %for.end ]
+ %conv41 = trunc i32 %sum.2 to i8
+ store i8 %conv41, i8* %arrayidx44.phi, align 1, !tbaa !1
+ %inc46 = add nsw i32 %j.085, 1
+ %exitcond87 = icmp eq i32 %inc46, %width
+ %arrayidx44.inc = getelementptr i8, i8* %arrayidx44.phi, i32 1
+ br i1 %exitcond87, label %for.inc48.loopexit, label %for.cond5.preheader
+
+for.inc48.loopexit: ; preds = %if.end40
+ br label %for.inc48
+
+for.inc48: ; preds = %for.inc48.loopexit, %for.body
+ %inc49 = add nsw i32 %i.086, 1
+ %exitcond88 = icmp eq i32 %inc49, 2
+ br i1 %exitcond88, label %for.end50, label %for.body
+
+for.end50: ; preds = %for.inc48
+ ret void
+}
+
+attributes #0 = { nounwind optsize readnone "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind optsize "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.ident = !{!0}
+
+!0 = !{!"Clang 3.1"}
+!1 = !{!2, !2, i64 0}
+!2 = !{!"omnipotent char", !3, i64 0}
+!3 = !{!"Simple C/C++ TBAA"}
--- /dev/null
+; RUN: llc -march=hexagon -enable-aa-sched-mi < %s
+; REQUIRES: asserts
+
+; Make sure the base is a register and not an address.
+
+define fastcc void @Get_lsp_pol(i32* nocapture %f) #0 {
+entry:
+ %f5 = alloca i32, align 4
+ %arrayidx103 = getelementptr inbounds i32, i32* %f, i32 4
+ store i32 0, i32* %arrayidx103, align 4
+ %f5.0.load185 = load volatile i32, i32* %f5, align 4
+ ret void
+}
+
+attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
--- /dev/null
+; RUN: llc -march=hexagon -mcpu=hexagonv5 < %s
+; REQUIRES: asserts
+
+; Test that the accessSize is set on a post-increment store. If not, an assert
+; is triggered in getBaseAndOffset()
+
+%struct.A = type { i8, i32, i32, i32, [10 x i32], [10 x i32], [80 x i32], [80 x i32], [8 x i32], i32, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16 }
+
+; Function Attrs: nounwind
+define fastcc void @Decoder_amr(i8 zeroext %mode) #0 {
+entry:
+ br label %for.cond64.preheader.i
+
+for.cond64.preheader.i:
+ %i.1984.i = phi i32 [ 0, %entry ], [ %inc166.i.1, %for.cond64.preheader.i ]
+ %inc166.i = add nsw i32 %i.1984.i, 1
+ %arrayidx71.i1422.1 = getelementptr inbounds %struct.A, %struct.A* undef, i32 0, i32 7, i32 %inc166.i
+ %storemerge800.i.1 = select i1 undef, i32 1310, i32 undef
+ %sub156.i.1 = sub nsw i32 0, %storemerge800.i.1
+ %sub156.storemerge800.i.1 = select i1 undef, i32 %storemerge800.i.1, i32 %sub156.i.1
+ store i32 %sub156.storemerge800.i.1, i32* %arrayidx71.i1422.1, align 4
+ store i32 0, i32* undef, align 4
+ %inc166.i.1 = add nsw i32 %i.1984.i, 2
+ br label %for.cond64.preheader.i
+
+if.end:
+ ret void
+}
+
+attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }