summaryrefslogtreecommitdiff
path: root/test/CodeGen/Hexagon
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGen/Hexagon')
-rw-r--r--test/CodeGen/Hexagon/Atomics.ll71
-rw-r--r--test/CodeGen/Hexagon/common-gep-basic.ll37
-rw-r--r--test/CodeGen/Hexagon/common-gep-icm.ll76
-rw-r--r--test/CodeGen/Hexagon/extract-basic.ll76
-rw-r--r--test/CodeGen/Hexagon/fusedandshift.ll3
-rw-r--r--test/CodeGen/Hexagon/insert-basic.ll66
-rw-r--r--test/CodeGen/Hexagon/predicate-logical.ll30
-rw-r--r--test/CodeGen/Hexagon/predicate-rcmp.ll19
8 files changed, 377 insertions, 1 deletions
diff --git a/test/CodeGen/Hexagon/Atomics.ll b/test/CodeGen/Hexagon/Atomics.ll
new file mode 100644
index 000000000000..bbac5d73c868
--- /dev/null
+++ b/test/CodeGen/Hexagon/Atomics.ll
@@ -0,0 +1,71 @@
+; RUN: llc < %s -march=hexagon
+
+@si = common global i32 0, align 4
+@sll = common global i64 0, align 8
+
+define void @test_op_ignore() nounwind {
+entry:
+ %t00 = atomicrmw add i32* @si, i32 1 monotonic
+ %t01 = atomicrmw add i64* @sll, i64 1 monotonic
+ %t10 = atomicrmw sub i32* @si, i32 1 monotonic
+ %t11 = atomicrmw sub i64* @sll, i64 1 monotonic
+ %t20 = atomicrmw or i32* @si, i32 1 monotonic
+ %t21 = atomicrmw or i64* @sll, i64 1 monotonic
+ %t30 = atomicrmw xor i32* @si, i32 1 monotonic
+ %t31 = atomicrmw xor i64* @sll, i64 1 monotonic
+ %t40 = atomicrmw and i32* @si, i32 1 monotonic
+ %t41 = atomicrmw and i64* @sll, i64 1 monotonic
+ %t50 = atomicrmw nand i32* @si, i32 1 monotonic
+ %t51 = atomicrmw nand i64* @sll, i64 1 monotonic
+ br label %return
+
+return: ; preds = %entry
+ ret void
+}
+
+define void @test_fetch_and_op() nounwind {
+entry:
+ %t00 = atomicrmw add i32* @si, i32 11 monotonic
+ store i32 %t00, i32* @si, align 4
+ %t01 = atomicrmw add i64* @sll, i64 11 monotonic
+ store i64 %t01, i64* @sll, align 8
+ %t10 = atomicrmw sub i32* @si, i32 11 monotonic
+ store i32 %t10, i32* @si, align 4
+ %t11 = atomicrmw sub i64* @sll, i64 11 monotonic
+ store i64 %t11, i64* @sll, align 8
+ %t20 = atomicrmw or i32* @si, i32 11 monotonic
+ store i32 %t20, i32* @si, align 4
+ %t21 = atomicrmw or i64* @sll, i64 11 monotonic
+ store i64 %t21, i64* @sll, align 8
+ %t30 = atomicrmw xor i32* @si, i32 11 monotonic
+ store i32 %t30, i32* @si, align 4
+ %t31 = atomicrmw xor i64* @sll, i64 11 monotonic
+ store i64 %t31, i64* @sll, align 8
+ %t40 = atomicrmw and i32* @si, i32 11 monotonic
+ store i32 %t40, i32* @si, align 4
+ %t41 = atomicrmw and i64* @sll, i64 11 monotonic
+ store i64 %t41, i64* @sll, align 8
+ %t50 = atomicrmw nand i32* @si, i32 11 monotonic
+ store i32 %t50, i32* @si, align 4
+ %t51 = atomicrmw nand i64* @sll, i64 11 monotonic
+ store i64 %t51, i64* @sll, align 8
+ br label %return
+
+return: ; preds = %entry
+ ret void
+}
+
+define void @test_lock() nounwind {
+entry:
+ %t00 = atomicrmw xchg i32* @si, i32 1 monotonic
+ store i32 %t00, i32* @si, align 4
+ %t01 = atomicrmw xchg i64* @sll, i64 1 monotonic
+ store i64 %t01, i64* @sll, align 8
+ fence seq_cst
+ store volatile i32 0, i32* @si, align 4
+ store volatile i64 0, i64* @sll, align 8
+ br label %return
+
+return: ; preds = %entry
+ ret void
+}
diff --git a/test/CodeGen/Hexagon/common-gep-basic.ll b/test/CodeGen/Hexagon/common-gep-basic.ll
new file mode 100644
index 000000000000..317bf868d0f8
--- /dev/null
+++ b/test/CodeGen/Hexagon/common-gep-basic.ll
@@ -0,0 +1,37 @@
+; RUN: llc -O2 -march=hexagon < %s | FileCheck %s
+; CHECK: mpyi
+; CHECK-NOT: mpyi
+; The mpyis from the two GEPs should be commoned out.
+
+target datalayout = "e-m:e-p:32:32-i64:64-a:0-v32:32-n16:32"
+target triple = "hexagon-unknown--elf"
+
+%struct.s_t = type { %struct.anon, i32 }
+%struct.anon = type { i32, [5 x i32] }
+
+@g = common global [100 x %struct.s_t] zeroinitializer, align 8
+
+; Function Attrs: nounwind
+define void @foo(i32 %x) #0 {
+entry:
+ %cmp = icmp slt i32 %x, 90
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %arrayidx1 = getelementptr inbounds [100 x %struct.s_t], [100 x %struct.s_t]* @g, i32 0, i32 %x, i32 0, i32 1, i32 2
+ tail call void @bar(i32* %arrayidx1) #0
+ br label %if.end
+
+if.else: ; preds = %entry
+ %arrayidx5 = getelementptr inbounds [100 x %struct.s_t], [100 x %struct.s_t]* @g, i32 0, i32 %x, i32 0, i32 1, i32 3
+ tail call void @bar(i32* %arrayidx5) #0
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then
+ ret void
+}
+
+declare void @bar(i32*) #0
+
+attributes #0 = { nounwind }
+
diff --git a/test/CodeGen/Hexagon/common-gep-icm.ll b/test/CodeGen/Hexagon/common-gep-icm.ll
new file mode 100644
index 000000000000..bc5719dfe1d0
--- /dev/null
+++ b/test/CodeGen/Hexagon/common-gep-icm.ll
@@ -0,0 +1,76 @@
+; RUN: llc -O2 -march=hexagon < %s | FileCheck %s
+; Rely on the comments generated by llc. Make sure there are no add/addasl
+; instructions in while.body13 (before the loads).
+; CHECK: while.body13
+; CHECK-NOT: add
+; CHECK: memw
+
+%struct.1 = type { i32, i32 }
+%struct.2 = type { [24 x i32], [24 x i32], [24 x i32], [24 x i32], [24 x i32], [24 x i32], [24 x i32], [24 x i32], [24 x i32], [24 x i32], [24 x i32], [24 x i32], [24 x i32], [24 x i32], [24 x i32], [24 x i32], [24 x i32], [3 x i32], [24 x i32], [8 x %struct.1], [5 x i32] }
+
+@A1 = global i64 zeroinitializer
+@A2 = global i64 zeroinitializer
+@B1 = global i32 zeroinitializer
+@B2 = global i32 zeroinitializer
+@C1 = global i8 zeroinitializer
+
+declare i32 @llvm.hexagon.S2.cl0(i32) nounwind readnone
+declare i32 @llvm.hexagon.S2.setbit.r(i32, i32) nounwind readnone
+declare i64 @llvm.hexagon.M2.vmpy2s.s0(i32, i32) nounwind readnone
+declare i64 @llvm.hexagon.M2.vmac2s.s0(i64, i32, i32) nounwind readnone
+declare i64 @llvm.hexagon.A2.vaddws(i64, i64) nounwind readnone
+declare i64 @llvm.hexagon.A2.vsubws(i64, i64) nounwind readnone
+declare i32 @llvm.hexagon.A4.modwrapu(i32, i32) nounwind readnone
+
+define void @foo(i32 %n) nounwind {
+entry:
+ br label %while.body
+
+while.body:
+ %count = phi i32 [ 0, %entry ], [ %next, %while.end ]
+ %idx = phi i32 [ 0, %entry ], [ %15, %while.end ]
+ %0 = load i32, i32* @B1, align 4
+ %1 = load i32, i32* @B2, align 8
+ %2 = and i32 %1, %0
+ br label %while.body13
+
+while.body13: ; preds = %while.body, %if.end
+ %3 = phi i64 [ %13, %if.end ], [ 0, %while.body ]
+ %4 = phi i64 [ %14, %if.end ], [ 0, %while.body ]
+ %m = phi i32 [ %6, %if.end ], [ %2, %while.body ]
+ %5 = tail call i32 @llvm.hexagon.S2.cl0(i32 %m)
+ %6 = tail call i32 @llvm.hexagon.S2.setbit.r(i32 %m, i32 %5)
+ %cgep85 = getelementptr [10 x %struct.2], [10 x %struct.2]* inttoptr (i32 -121502345 to [10 x %struct.2]*), i32 0, i32 %idx
+ %cgep90 = getelementptr %struct.2, %struct.2* %cgep85, i32 0, i32 12, i32 %5
+ %7 = load i32, i32* %cgep90, align 4
+ %8 = tail call i64 @llvm.hexagon.M2.vmpy2s.s0(i32 %7, i32 %7)
+ %cgep91 = getelementptr %struct.2, %struct.2* %cgep85, i32 0, i32 13, i32 %5
+ %9 = load i32, i32* %cgep91, align 4
+ %10 = tail call i64 @llvm.hexagon.M2.vmac2s.s0(i64 %8, i32 %9, i32 %9)
+ %11 = load i8, i8* @C1, align 1
+ %and24 = and i8 %11, 1
+ %cmp = icmp eq i8 %and24, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %while.body13
+ %12 = tail call i64 @llvm.hexagon.A2.vaddws(i64 %3, i64 %10)
+ store i64 %12, i64* @A1, align 8
+ br label %if.end
+
+if.end: ; preds = %if.then, %while.body13
+ %13 = phi i64 [ %12, %if.then ], [ %3, %while.body13 ]
+ %14 = tail call i64 @llvm.hexagon.A2.vsubws(i64 %4, i64 %10)
+ %tobool12 = icmp eq i32 %6, 0
+ br i1 %tobool12, label %while.end, label %while.body13
+
+while.end:
+ %add40 = add i32 %idx, 1
+ %15 = tail call i32 @llvm.hexagon.A4.modwrapu(i32 %add40, i32 10) nounwind
+ %next = add i32 %count, 1
+ %cc = icmp eq i32 %next, %n
+ br i1 %cc, label %end, label %while.body
+
+end:
+ store i64 %10, i64* @A2, align 8
+ ret void
+}
diff --git a/test/CodeGen/Hexagon/extract-basic.ll b/test/CodeGen/Hexagon/extract-basic.ll
new file mode 100644
index 000000000000..c75125cedd35
--- /dev/null
+++ b/test/CodeGen/Hexagon/extract-basic.ll
@@ -0,0 +1,76 @@
+; RUN: llc -O2 -march=hexagon < %s | FileCheck %s
+
+; CHECK-DAG: extractu(r{{[0-9]*}}, #3, #4)
+; CHECK-DAG: extractu(r{{[0-9]*}}, #8, #7)
+; CHECK-DAG: extractu(r{{[0-9]*}}, #8, #16)
+
+; C source:
+; typedef struct {
+; unsigned x1:3;
+; unsigned x2:7;
+; unsigned x3:8;
+; unsigned x4:12;
+; unsigned x5:2;
+; } structx_t;
+;
+; typedef struct {
+; unsigned y1:4;
+; unsigned y2:3;
+; unsigned y3:9;
+; unsigned y4:8;
+; unsigned y5:8;
+; } structy_t;
+;
+; void foo(structx_t *px, structy_t *py) {
+; px->x1 = py->y1;
+; px->x2 = py->y2;
+; px->x3 = py->y3;
+; px->x4 = py->y4;
+; px->x5 = py->y5;
+; }
+
+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.structx_t = type { i8, i8, i8, i8 }
+%struct.structy_t = type { i8, i8, i8, i8 }
+
+define void @foo(%struct.structx_t* nocapture %px, %struct.structy_t* nocapture %py) nounwind {
+entry:
+ %0 = bitcast %struct.structy_t* %py to i32*
+ %1 = load i32, i32* %0, align 4
+ %bf.value = and i32 %1, 7
+ %2 = bitcast %struct.structx_t* %px to i32*
+ %3 = load i32, i32* %2, align 4
+ %4 = and i32 %3, -8
+ %5 = or i32 %4, %bf.value
+ store i32 %5, i32* %2, align 4
+ %6 = load i32, i32* %0, align 4
+ %7 = lshr i32 %6, 4
+ %bf.clear1 = shl nuw nsw i32 %7, 3
+ %8 = and i32 %bf.clear1, 56
+ %9 = and i32 %5, -1017
+ %10 = or i32 %8, %9
+ store i32 %10, i32* %2, align 4
+ %11 = load i32, i32* %0, align 4
+ %12 = lshr i32 %11, 7
+ %bf.value4 = shl i32 %12, 10
+ %13 = and i32 %bf.value4, 261120
+ %14 = and i32 %10, -262081
+ %15 = or i32 %14, %13
+ store i32 %15, i32* %2, align 4
+ %16 = load i32, i32* %0, align 4
+ %17 = lshr i32 %16, 16
+ %bf.clear5 = shl i32 %17, 18
+ %18 = and i32 %bf.clear5, 66846720
+ %19 = and i32 %15, -1073480641
+ %20 = or i32 %19, %18
+ store i32 %20, i32* %2, align 4
+ %21 = load i32, i32* %0, align 4
+ %22 = lshr i32 %21, 24
+ %23 = shl i32 %22, 30
+ %24 = and i32 %20, 67107903
+ %25 = or i32 %24, %23
+ store i32 %25, i32* %2, align 4
+ ret void
+}
diff --git a/test/CodeGen/Hexagon/fusedandshift.ll b/test/CodeGen/Hexagon/fusedandshift.ll
index 59a1e1d84fcc..414574aec401 100644
--- a/test/CodeGen/Hexagon/fusedandshift.ll
+++ b/test/CodeGen/Hexagon/fusedandshift.ll
@@ -1,5 +1,6 @@
-; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s
+; RUN: llc -march=hexagon -hexagon-extract=0 < %s | FileCheck %s
; Check that we generate fused logical and with shift instruction.
+; Disable "extract" generation, since it may eliminate the and/lsr.
; CHECK: r{{[0-9]+}} = and(#15, lsr(r{{[0-9]+}}, #{{[0-9]+}})
diff --git a/test/CodeGen/Hexagon/insert-basic.ll b/test/CodeGen/Hexagon/insert-basic.ll
new file mode 100644
index 000000000000..e941c063d9ed
--- /dev/null
+++ b/test/CodeGen/Hexagon/insert-basic.ll
@@ -0,0 +1,66 @@
+; RUN: llc -O2 -march=hexagon < %s | FileCheck %s
+; CHECK-DAG: insert(r{{[0-9]*}}, #17, #0)
+; CHECK-DAG: insert(r{{[0-9]*}}, #18, #0)
+; CHECK-DAG: insert(r{{[0-9]*}}, #22, #0)
+; CHECK-DAG: insert(r{{[0-9]*}}, #12, #0)
+
+; C source:
+; typedef struct {
+; unsigned x1:23;
+; unsigned x2:17;
+; unsigned x3:18;
+; unsigned x4:22;
+; unsigned x5:12;
+; } structx_t;
+;
+; void foo(structx_t *px, int y1, int y2, int y3, int y4, int y5) {
+; px->x1 = y1;
+; px->x2 = y2;
+; px->x3 = y3;
+; px->x4 = y4;
+; px->x5 = y5;
+; }
+
+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.structx_t = type { [3 x i8], i8, [3 x i8], i8, [3 x i8], i8, [3 x i8], i8, [2 x i8], [2 x i8] }
+
+define void @foo(%struct.structx_t* nocapture %px, i32 %y1, i32 %y2, i32 %y3, i32 %y4, i32 %y5) nounwind {
+entry:
+ %bf.value = and i32 %y1, 8388607
+ %0 = bitcast %struct.structx_t* %px to i32*
+ %1 = load i32, i32* %0, align 4
+ %2 = and i32 %1, -8388608
+ %3 = or i32 %2, %bf.value
+ store i32 %3, i32* %0, align 4
+ %bf.value1 = and i32 %y2, 131071
+ %bf.field.offs = getelementptr %struct.structx_t, %struct.structx_t* %px, i32 0, i32 0, i32 4
+ %4 = bitcast i8* %bf.field.offs to i32*
+ %5 = load i32, i32* %4, align 4
+ %6 = and i32 %5, -131072
+ %7 = or i32 %6, %bf.value1
+ store i32 %7, i32* %4, align 4
+ %bf.value2 = and i32 %y3, 262143
+ %bf.field.offs3 = getelementptr %struct.structx_t, %struct.structx_t* %px, i32 0, i32 0, i32 8
+ %8 = bitcast i8* %bf.field.offs3 to i32*
+ %9 = load i32, i32* %8, align 4
+ %10 = and i32 %9, -262144
+ %11 = or i32 %10, %bf.value2
+ store i32 %11, i32* %8, align 4
+ %bf.value4 = and i32 %y4, 4194303
+ %bf.field.offs5 = getelementptr %struct.structx_t, %struct.structx_t* %px, i32 0, i32 0, i32 12
+ %12 = bitcast i8* %bf.field.offs5 to i32*
+ %13 = load i32, i32* %12, align 4
+ %14 = and i32 %13, -4194304
+ %15 = or i32 %14, %bf.value4
+ store i32 %15, i32* %12, align 4
+ %bf.value6 = and i32 %y5, 4095
+ %bf.field.offs7 = getelementptr %struct.structx_t, %struct.structx_t* %px, i32 0, i32 0, i32 16
+ %16 = bitcast i8* %bf.field.offs7 to i32*
+ %17 = load i32, i32* %16, align 4
+ %18 = and i32 %17, -4096
+ %19 = or i32 %18, %bf.value6
+ store i32 %19, i32* %16, align 4
+ ret void
+}
diff --git a/test/CodeGen/Hexagon/predicate-logical.ll b/test/CodeGen/Hexagon/predicate-logical.ll
new file mode 100644
index 000000000000..be2bcb03d6a1
--- /dev/null
+++ b/test/CodeGen/Hexagon/predicate-logical.ll
@@ -0,0 +1,30 @@
+; RUN: llc -O2 -march=hexagon < %s | FileCheck %s
+; CHECK: p{{[0-9]}} = or(p{{[0-9]}}, and(p{{[0-9]}}, p{{[0-9]}}))
+
+target triple = "hexagon"
+
+define i32 @foo(i64* nocapture %p, i64* nocapture %q) nounwind readonly {
+entry:
+ %incdec.ptr = getelementptr inbounds i64, i64* %p, i32 1
+ %0 = load i64, i64* %p, align 8, !tbaa !0
+ %incdec.ptr1 = getelementptr inbounds i64, i64* %q, i32 1
+ %1 = load i64, i64* %q, align 8, !tbaa !0
+ %2 = tail call i32 @llvm.hexagon.A2.vcmpwgtu(i64 %0, i64 %1)
+ %incdec.ptr2 = getelementptr inbounds i64, i64* %p, i32 2
+ %3 = load i64, i64* %incdec.ptr, align 8, !tbaa !0
+ %incdec.ptr3 = getelementptr inbounds i64, i64* %q, i32 2
+ %4 = load i64, i64* %incdec.ptr1, align 8, !tbaa !0
+ %5 = tail call i32 @llvm.hexagon.A2.vcmpwgtu(i64 %3, i64 %4)
+ %6 = load i64, i64* %incdec.ptr2, align 8, !tbaa !0
+ %7 = load i64, i64* %incdec.ptr3, align 8, !tbaa !0
+ %8 = tail call i32 @llvm.hexagon.A2.vcmpwgtu(i64 %6, i64 %7)
+ %and = and i32 %5, %2
+ %or = or i32 %8, %and
+ ret i32 %or
+}
+
+declare i32 @llvm.hexagon.A2.vcmpwgtu(i64, i64) nounwind readnone
+
+!0 = !{!"long long", !1}
+!1 = !{!"omnipotent char", !2}
+!2 = !{!"Simple C/C++ TBAA"}
diff --git a/test/CodeGen/Hexagon/predicate-rcmp.ll b/test/CodeGen/Hexagon/predicate-rcmp.ll
new file mode 100644
index 000000000000..45daa88d7161
--- /dev/null
+++ b/test/CodeGen/Hexagon/predicate-rcmp.ll
@@ -0,0 +1,19 @@
+; RUN: llc -O2 -march=hexagon < %s | FileCheck %s
+; CHECK: cmp.eq(r{{[0-9]+}}, #0)
+; Check that the result of the builtin is not stored directly, i.e. that
+; there is an instruction that converts it to {0,1} from {0,-1}. Right now
+; the instruction is "r4 = !cmp.eq(r0, #0)".
+
+@var = common global i32 0, align 4
+declare i32 @llvm.hexagon.C2.cmpgtup(i64,i64) nounwind
+
+define void @foo(i64 %a98, i64 %a100) nounwind {
+entry:
+ %a101 = tail call i32 @llvm.hexagon.C2.cmpgtup(i64 %a98, i64 %a100)
+ %tobool250 = icmp eq i32 %a101, 0
+ %a102 = zext i1 %tobool250 to i8
+ %detected.0 = xor i8 %a102, 1
+ %conv253 = zext i8 %detected.0 to i32
+ store i32 %conv253, i32* @var, align 4
+ ret void
+}