diff options
Diffstat (limited to 'test/CodeGen/Hexagon')
| -rw-r--r-- | test/CodeGen/Hexagon/Atomics.ll | 71 | ||||
| -rw-r--r-- | test/CodeGen/Hexagon/common-gep-basic.ll | 37 | ||||
| -rw-r--r-- | test/CodeGen/Hexagon/common-gep-icm.ll | 76 | ||||
| -rw-r--r-- | test/CodeGen/Hexagon/extract-basic.ll | 76 | ||||
| -rw-r--r-- | test/CodeGen/Hexagon/fusedandshift.ll | 3 | ||||
| -rw-r--r-- | test/CodeGen/Hexagon/insert-basic.ll | 66 | ||||
| -rw-r--r-- | test/CodeGen/Hexagon/predicate-logical.ll | 30 | ||||
| -rw-r--r-- | test/CodeGen/Hexagon/predicate-rcmp.ll | 19 |
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 +} |
