diff options
Diffstat (limited to 'llvm/test/CodeGen/ARM/dsp-loop-indexing.ll')
-rw-r--r-- | llvm/test/CodeGen/ARM/dsp-loop-indexing.ll | 310 |
1 files changed, 310 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/ARM/dsp-loop-indexing.ll b/llvm/test/CodeGen/ARM/dsp-loop-indexing.ll new file mode 100644 index 00000000000..7b80b400af4 --- /dev/null +++ b/llvm/test/CodeGen/ARM/dsp-loop-indexing.ll @@ -0,0 +1,310 @@ +; RUN: llc -mtriple=thumbv7em -mattr=+fp-armv8 %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DEFAULT +; RUN: llc -mtriple=thumbv8m.main -mattr=+fp-armv8,+dsp %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DEFAULT +; RUN: llc -mtriple=thumbv8m.main -mattr=+fp-armv8,+dsp -lsr-backedge-indexing=false %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLED +; RUN: llc -mtriple=thumbv8 %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLED +; RUN: llc -mtriple=thumbv8m.main -mattr=+fp-armv8,+dsp -lsr-complexity-limit=2147483647 %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-COMPLEX + +; CHECK-LABEL: test_qadd_2 +; CHECK: @ %loop + +; CHECK-DEFAULT: ldr{{.*}}, #4] +; CHECK-DEFAULT: ldr{{.*}}, #4] +; CHECK-DEFAULT: str{{.*}}, #4] +; CHECK-DEFAULT: ldr{{.*}}, #8]! +; CHECK-DEAFULT: ldr{{.*}}, #8]! +; CHECK-DEFAULT: str{{.*}}, #8]! + +; CHECK-COMPLEX: ldr{{.*}}, #8]! +; CHECK-COMPLEX: ldr{{.*}}, #8]! +; CHECK-COMPLEX: str{{.*}}, #8]! +; CHECK-COMPLEX: ldr{{.*}}, #4] +; CHECK-COMPLEX: ldr{{.*}}, #4] +; CHECK-COMPLEX: str{{.*}}, #4] + +; DISABLED-NOT: ldr{{.*}}]! +; DISABLED-NOT: str{{.*}}]! + +define void @test_qadd_2(i32* %a.array, i32* %b.array, i32* %out.array, i32 %N) { +entry: + br label %loop + +loop: + %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] + %idx.1 = phi i32 [ 0, %entry ], [ %idx.next, %loop ] + %gep.a.1 = getelementptr inbounds i32, i32* %a.array, i32 %idx.1 + %a.1 = load i32, i32* %gep.a.1 + %gep.b.1 = getelementptr inbounds i32, i32* %b.array, i32 %idx.1 + %b.1 = load i32, i32* %gep.b.1 + %qadd.1 = call i32 @llvm.arm.qadd(i32 %a.1, i32 %b.1) + %addr.1 = getelementptr inbounds i32, i32* %out.array, i32 %idx.1 + store i32 %qadd.1, i32* %addr.1 + %idx.2 = or i32 %idx.1, 1 + %gep.a.2 = getelementptr inbounds i32, i32* %a.array, i32 %idx.2 + %a.2 = load i32, i32* %gep.a.2 + %gep.b.2 = getelementptr inbounds i32, i32* %b.array, i32 %idx.2 + %b.2 = load i32, i32* %gep.b.2 + %qadd.2 = call i32 @llvm.arm.qadd(i32 %a.2, i32 %b.2) + %addr.2 = getelementptr inbounds i32, i32* %out.array, i32 %idx.2 + store i32 %qadd.2, i32* %addr.2 + %i.next = add nsw nuw i32 %i, -2 + %idx.next = add nsw nuw i32 %idx.1, 2 + %cmp = icmp ult i32 %i.next, %N + br i1 %cmp, label %loop, label %exit + +exit: + ret void +} + +; CHECK-LABEL: test_qadd_2_backwards +; TODO: Indexes should be generated. + +; CHECK: @ %loop + +; CHECK-DEFAULT: ldr{{.*}}, +; CHECK-DEFAULT: ldr{{.*}}, +; CHECK-DEFAULT: str{{.*}}, +; CHECK-DEFAULT: ldr{{.*}}, #-4] +; CHECK-DEFAULT: ldr{{.*}}, #-4] +; CHECK-DEFAULT: sub{{.*}}, #8 +; CHECK-DEFAULT: str{{.*}}, #-4] +; CHECK-DEFAULT: sub{{.*}}, #8 + +; CHECK-COMPLEX: ldr{{.*}} lsl #2] +; CHECK-COMPLEX: ldr{{.*}} lsl #2] +; CHECK-COMPLEX: str{{.*}} lsl #2] +; CHECK-COMPLEX: ldr{{.*}} lsl #2] +; CHECK-COMPLEX: ldr{{.*}} lsl #2] +; CHECK-COMPLEX: str{{.*}} lsl #2] + +; DISABLED-NOT: ldr{{.*}}]! +; DISABLED-NOT: str{{.*}}]! + +define void @test_qadd_2_backwards(i32* %a.array, i32* %b.array, i32* %out.array, i32 %N) { +entry: + br label %loop + +loop: + %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] + %idx.1 = phi i32 [ %N, %entry ], [ %idx.next, %loop ] + %gep.a.1 = getelementptr inbounds i32, i32* %a.array, i32 %idx.1 + %a.1 = load i32, i32* %gep.a.1 + %gep.b.1 = getelementptr inbounds i32, i32* %b.array, i32 %idx.1 + %b.1 = load i32, i32* %gep.b.1 + %qadd.1 = call i32 @llvm.arm.qadd(i32 %a.1, i32 %b.1) + %addr.1 = getelementptr inbounds i32, i32* %out.array, i32 %idx.1 + store i32 %qadd.1, i32* %addr.1 + %idx.2 = sub nsw nuw i32 %idx.1, 1 + %gep.a.2 = getelementptr inbounds i32, i32* %a.array, i32 %idx.2 + %a.2 = load i32, i32* %gep.a.2 + %gep.b.2 = getelementptr inbounds i32, i32* %b.array, i32 %idx.2 + %b.2 = load i32, i32* %gep.b.2 + %qadd.2 = call i32 @llvm.arm.qadd(i32 %a.2, i32 %b.2) + %addr.2 = getelementptr inbounds i32, i32* %out.array, i32 %idx.2 + store i32 %qadd.2, i32* %addr.2 + %i.next = add nsw nuw i32 %i, -2 + %idx.next = sub nsw nuw i32 %idx.1, 2 + %cmp = icmp ult i32 %i.next, %N + br i1 %cmp, label %loop, label %exit + +exit: + ret void +} + +; CHECK-LABEL: test_qadd_3 +; CHECK: @ %loop + +; CHECK-DEFAULT: ldr{{.*}}, #8] +; CHECK-DEFAULT: ldr{{.*}}, #8] +; CHECK-DEFAULT: str{{.*}}, #8] +; CHECK-DEFAULT: ldr{{.*}}, #12]! +; CHECK-DEFAULT: ldr{{.*}}, #12]! +; CHECK-DEFAULT: str{{.*}}, #12]! + +; CHECK-COMPLEX: ldr{{.*}}, #12]! +; CHECK-COMPLEX: ldr{{.*}}, #12]! +; CHECK-COMPLEX: str{{.*}}, #12]! +; CHECK-COMPLEX: ldr{{.*}}, #4] +; CHECK-COMPLEX: ldr{{.*}}, #4] +; CHECK-COMPLEX: str{{.*}}, #4] +; CHECK-COMPLEX: ldr{{.*}}, #8] +; CHECK-COMPLEX: ldr{{.*}}, #8] +; CHECK-COMPLEX: str{{.*}}, #8] + +; DISABLED-NOT: ldr{{.*}}]! +; DISABLED-NOT: str{{.*}}]! + +define void @test_qadd_3(i32* %a.array, i32* %b.array, i32* %out.array, i32 %N) { +entry: + br label %loop + +loop: + %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] + %idx.1 = phi i32 [ 0, %entry ], [ %idx.next, %loop ] + %gep.a.1 = getelementptr inbounds i32, i32* %a.array, i32 %idx.1 + %a.1 = load i32, i32* %gep.a.1 + %gep.b.1 = getelementptr inbounds i32, i32* %b.array, i32 %idx.1 + %b.1 = load i32, i32* %gep.b.1 + %qadd.1 = call i32 @llvm.arm.qadd(i32 %a.1, i32 %b.1) + %addr.1 = getelementptr inbounds i32, i32* %out.array, i32 %idx.1 + store i32 %qadd.1, i32* %addr.1 + %idx.2 = add nuw nsw i32 %idx.1, 1 + %gep.a.2 = getelementptr inbounds i32, i32* %a.array, i32 %idx.2 + %a.2 = load i32, i32* %gep.a.2 + %gep.b.2 = getelementptr inbounds i32, i32* %b.array, i32 %idx.2 + %b.2 = load i32, i32* %gep.b.2 + %qadd.2 = call i32 @llvm.arm.qadd(i32 %a.2, i32 %b.2) + %addr.2 = getelementptr inbounds i32, i32* %out.array, i32 %idx.2 + store i32 %qadd.2, i32* %addr.2 + %idx.3 = add nuw nsw i32 %idx.1, 2 + %gep.a.3 = getelementptr inbounds i32, i32* %a.array, i32 %idx.3 + %a.3 = load i32, i32* %gep.a.3 + %gep.b.3 = getelementptr inbounds i32, i32* %b.array, i32 %idx.3 + %b.3 = load i32, i32* %gep.b.3 + %qadd.3 = call i32 @llvm.arm.qadd(i32 %a.3, i32 %b.3) + %addr.3 = getelementptr inbounds i32, i32* %out.array, i32 %idx.3 + store i32 %qadd.3, i32* %addr.3 + %i.next = add nsw nuw i32 %i, -3 + %idx.next = add nsw nuw i32 %idx.1, 3 + %cmp = icmp ult i32 %i.next, %N + br i1 %cmp, label %loop, label %exit + +exit: + ret void +} + +; CHECK-LABEL: test_qadd_4 +; CHECK: @ %loop + +; TODO: pre-inc store + +; CHECK-DEFAULT: ldr{{.*}}, #4] +; CHECK-DEFAULT: ldr{{.*}}, #4] +; CHECK-DEFAULT: str{{.*}}, #4] +; CHECK-DEFAULT: ldr{{.*}}, #8] +; CHECK-DEFAULT: ldr{{.*}}, #8] +; CHECK-DEFAULT: str{{.*}}, #8] +; CHECK-DEFAULT: ldr{{.*}}, #12] +; CHECK-DEFAULT: ldr{{.*}}, #12] +; CHECK-DEFAULT: str{{.*}}, #12] + +; CHECK-COMPLEX: ldr{{.*}}, #16]! +; CHECK-COMPLEX: ldr{{.*}}, #16]! +; CHECK-COMPLEX: str{{.*}}, #16]! +; CHECK-COMPLEX: ldr{{.*}}, #4] +; CHECK-COMPLEX: ldr{{.*}}, #4] +; CHECK-COMPLEX: str{{.*}}, #4] +; CHECK-COMPLEX: ldr{{.*}}, #8] +; CHECK-COMPLEX: ldr{{.*}}, #8] +; CHECK-COMPLEX: str{{.*}}, #8] +; CHECK-COMPLEX: ldr{{.*}}, #12] +; CHECK-COMPLEX: ldr{{.*}}, #12] +; CHECK-COMPLEX: str{{.*}}, #12] + +; DISABLED-NOT: ldr{{.*}}]! +; DISABLED-NOT: str{{.*}}]! + +define void @test_qadd_4(i32* %a.array, i32* %b.array, i32* %out.array, i32 %N) { +entry: + br label %loop + +loop: + %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] + %idx.1 = phi i32 [ 0, %entry ], [ %idx.next, %loop ] + %gep.a.1 = getelementptr inbounds i32, i32* %a.array, i32 %idx.1 + %a.1 = load i32, i32* %gep.a.1 + %gep.b.1 = getelementptr inbounds i32, i32* %b.array, i32 %idx.1 + %b.1 = load i32, i32* %gep.b.1 + %qadd.1 = call i32 @llvm.arm.qadd(i32 %a.1, i32 %b.1) + %addr.1 = getelementptr inbounds i32, i32* %out.array, i32 %idx.1 + store i32 %qadd.1, i32* %addr.1 + %idx.2 = or i32 %idx.1, 1 + %gep.a.2 = getelementptr inbounds i32, i32* %a.array, i32 %idx.2 + %a.2 = load i32, i32* %gep.a.2 + %gep.b.2 = getelementptr inbounds i32, i32* %b.array, i32 %idx.2 + %b.2 = load i32, i32* %gep.b.2 + %qadd.2 = call i32 @llvm.arm.qadd(i32 %a.2, i32 %b.2) + %addr.2 = getelementptr inbounds i32, i32* %out.array, i32 %idx.2 + store i32 %qadd.2, i32* %addr.2 + %idx.3 = or i32 %idx.1, 2 + %gep.a.3 = getelementptr inbounds i32, i32* %a.array, i32 %idx.3 + %a.3 = load i32, i32* %gep.a.3 + %gep.b.3 = getelementptr inbounds i32, i32* %b.array, i32 %idx.3 + %b.3 = load i32, i32* %gep.b.3 + %qadd.3 = call i32 @llvm.arm.qadd(i32 %a.3, i32 %b.3) + %addr.3 = getelementptr inbounds i32, i32* %out.array, i32 %idx.3 + store i32 %qadd.3, i32* %addr.3 + %idx.4 = or i32 %idx.1, 3 + %gep.a.4 = getelementptr inbounds i32, i32* %a.array, i32 %idx.4 + %a.4 = load i32, i32* %gep.a.4 + %gep.b.4 = getelementptr inbounds i32, i32* %b.array, i32 %idx.4 + %b.4 = load i32, i32* %gep.b.4 + %qadd.4 = call i32 @llvm.arm.qadd(i32 %a.4, i32 %b.4) + %addr.4 = getelementptr inbounds i32, i32* %out.array, i32 %idx.4 + store i32 %qadd.4, i32* %addr.4 + %i.next = add nsw nuw i32 %i, -4 + %idx.next = add nsw nuw i32 %idx.1, 4 + %cmp = icmp ult i32 %i.next, %N + br i1 %cmp, label %loop, label %exit + +exit: + ret void +} + +; CHECK-LABEL: test_qadd16_2 +; CHECK: @ %loop +; TODO: pre-inc store. + +; CHECK-DEFAULT: ldr{{.*}}, #4] +; CHECK-DEFAULT: ldr{{.*}}, #4] +; CHECK-DEFAULT: str{{.*}}, #8] +; CHECK-DEFAULT: ldr{{.*}}, #8]! +; CHECK-DEFAULT: ldr{{.*}}, #8]! +; CHECK-DEFAULT: str{{.*}}, #16]! + +; CHECK-COMPLEX: ldr{{.*}}, #8]! +; CHECK-COMPLEX: ldr{{.*}}, #8]! +; CHECK-COMPLEX: str{{.*}}, #16]! +; CHECK-COMPLEX: ldr{{.*}}, #4] +; CHECK-COMPLEX: ldr{{.*}}, #4] +; CHECK-COMPLEX: str{{.*}}, #8] + +; DISABLED-NOT: ldr{{.*}}]! +; DISABLED-NOT: str{{.*}}]! + +define void @test_qadd16_2(i16* %a.array, i16* %b.array, i32* %out.array, i32 %N) { +entry: + br label %loop + +loop: + %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] + %idx.1 = phi i32 [ 0, %entry ], [ %idx.next, %loop ] + %gep.a.1 = getelementptr inbounds i16, i16* %a.array, i32 %idx.1 + %cast.a.1 = bitcast i16* %gep.a.1 to i32* + %a.1 = load i32, i32* %cast.a.1 + %gep.b.1 = getelementptr inbounds i16, i16* %b.array, i32 %idx.1 + %cast.b.1 = bitcast i16* %gep.b.1 to i32* + %b.1 = load i32, i32* %cast.b.1 + %qadd.1 = call i32 @llvm.arm.qadd16(i32 %a.1, i32 %b.1) + %addr.1 = getelementptr inbounds i32, i32* %out.array, i32 %idx.1 + store i32 %qadd.1, i32* %addr.1 + %idx.2 = add nsw nuw i32 %idx.1, 2 + %gep.a.2 = getelementptr inbounds i16, i16* %a.array, i32 %idx.2 + %cast.a.2 = bitcast i16* %gep.a.2 to i32* + %a.2 = load i32, i32* %cast.a.2 + %gep.b.2 = getelementptr inbounds i16, i16* %b.array, i32 %idx.2 + %cast.b.2 = bitcast i16* %gep.b.2 to i32* + %b.2 = load i32, i32* %cast.b.2 + %qadd.2 = call i32 @llvm.arm.qadd16(i32 %a.2, i32 %b.2) + %addr.2 = getelementptr inbounds i32, i32* %out.array, i32 %idx.2 + store i32 %qadd.2, i32* %addr.2 + %i.next = add nsw nuw i32 %i, -2 + %idx.next = add nsw nuw i32 %idx.1, 4 + %cmp = icmp ult i32 %i.next, %N + br i1 %cmp, label %loop, label %exit + +exit: + ret void +} + +declare i32 @llvm.arm.qadd(i32, i32) +declare i32 @llvm.arm.qadd16(i32, i32) |