summaryrefslogtreecommitdiffstats
path: root/llvm/test
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2014-04-03 15:10:35 +0000
committerTim Northover <tnorthover@apple.com>2014-04-03 15:10:35 +0000
commit01b4aa94371345be8e19129ccd9c6814f9c0e6aa (patch)
tree03ee37a4fd0f15c9b5dfcc2baff4896eb1679263 /llvm/test
parent0dcccf7bf3c1c8dfcfb8a92940c3240f8a2f7749 (diff)
downloadbcm5719-llvm-01b4aa94371345be8e19129ccd9c6814f9c0e6aa.tar.gz
bcm5719-llvm-01b4aa94371345be8e19129ccd9c6814f9c0e6aa.zip
ARM: tell LLVM about zext properties of ldrexb/ldrexh
Implementing this via ComputeMaskedBits has two advantages: + It actually works. DAGISel doesn't deal with the chains properly in the previous pattern-based solution, so they never trigger. + The information can be used in other DAG combines, as well as the trivial "get rid of truncs". For example if the trunc is in a different basic block. rdar://problem/16227836 llvm-svn: 205540
Diffstat (limited to 'llvm/test')
-rw-r--r--llvm/test/CodeGen/ARM/atomic-ops-v8.ll22
-rw-r--r--llvm/test/CodeGen/ARM/ldaex-stlex.ll12
-rw-r--r--llvm/test/CodeGen/ARM/ldstrex.ll28
3 files changed, 42 insertions, 20 deletions
diff --git a/llvm/test/CodeGen/ARM/atomic-ops-v8.ll b/llvm/test/CodeGen/ARM/atomic-ops-v8.ll
index 00f9006c155..7922e222030 100644
--- a/llvm/test/CodeGen/ARM/atomic-ops-v8.ll
+++ b/llvm/test/CodeGen/ARM/atomic-ops-v8.ll
@@ -805,8 +805,8 @@ define i8 @test_atomic_load_umin_i8(i8 zeroext %offset) nounwind {
; CHECK: ldrexb r[[OLD:[0-9]+]], {{.*}}[[ADDR]]
; r0 below is a reasonable guess but could change: it certainly comes into the
; function there.
-; CHECK-NEXT: uxtb r[[OLDX]], r[[OLD]]
-; CHECK-NEXT: cmp r[[OLDX]], r0
+; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0
+; CHECK-NEXT: cmp r[[OLD]], r0
; Thumb mode: it ls
; CHECK: movls r[[NEW]], r[[OLD]]
; CHECK-NEXT: strexb [[STATUS:r[0-9]+]], r[[NEW]], {{.*}}[[ADDR]]
@@ -831,8 +831,8 @@ define i16 @test_atomic_load_umin_i16(i16 zeroext %offset) nounwind {
; CHECK: ldaexh r[[OLD:[0-9]+]], {{.*}}[[ADDR]]
; r0 below is a reasonable guess but could change: it certainly comes into the
; function there.
-; CHECK-NEXT: uxth r[[OLDX]], r[[OLD]]
-; CHECK-NEXT: cmp r[[OLDX]], r0
+; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0
+; CHECK-NEXT: cmp r[[OLD]], r0
; Thumb mode: it ls
; CHECK: movls r[[NEW]], r[[OLD]]
; CHECK-NEXT: strexh [[STATUS:r[0-9]+]], r[[NEW]], {{.*}}[[ADDR]]
@@ -919,8 +919,8 @@ define i8 @test_atomic_load_umax_i8(i8 zeroext %offset) nounwind {
; CHECK: ldaexb r[[OLD:[0-9]+]], {{.*}}[[ADDR]]
; r0 below is a reasonable guess but could change: it certainly comes into the
; function there.
-; CHECK-NEXT: uxtb r[[OLDX:[0-9]+]], r[[OLD]]
-; CHECK-NEXT: cmp r[[OLDX]], r0
+; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0
+; CHECK-NEXT: cmp r[[OLD]], r0
; Thumb mode: it hi
; CHECK: movhi r[[NEW]], r[[OLD]]
; CHECK-NEXT: stlexb [[STATUS:r[0-9]+]], r[[NEW]], {{.*}}[[ADDR]]
@@ -945,8 +945,8 @@ define i16 @test_atomic_load_umax_i16(i16 zeroext %offset) nounwind {
; CHECK: ldrexh r[[OLD:[0-9]+]], {{.*}}[[ADDR]]
; r0 below is a reasonable guess but could change: it certainly comes into the
; function there.
-; CHECK-NEXT: uxth r[[OLDX:[0-9]+]], r[[OLD]]
-; CHECK-NEXT: cmp r[[OLDX]], r0
+; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0
+; CHECK-NEXT: cmp r[[OLD]], r0
; Thumb mode: it hi
; CHECK: movhi r[[NEW]], r[[OLD]]
; CHECK-NEXT: strexh [[STATUS:r[0-9]+]], r[[NEW]], {{.*}}[[ADDR]]
@@ -1033,8 +1033,7 @@ define i8 @test_atomic_cmpxchg_i8(i8 zeroext %wanted, i8 zeroext %new) nounwind
; CHECK: ldaexb r[[OLD:[0-9]+]], [r[[ADDR]]]
; r0 below is a reasonable guess but could change: it certainly comes into the
; function there.
-; CHECK-NEXT: uxtb r[[OLDX:[0-9]+]], r[[OLD]]
-; CHECK-NEXT: cmp r[[OLDX]], r0
+; CHECK-NEXT: cmp r[[OLD]], r0
; CHECK-NEXT: bne .LBB{{[0-9]+}}_3
; CHECK-NEXT: BB#2:
; As above, r1 is a reasonable guess.
@@ -1060,8 +1059,7 @@ define i16 @test_atomic_cmpxchg_i16(i16 zeroext %wanted, i16 zeroext %new) nounw
; CHECK: ldaexh r[[OLD:[0-9]+]], [r[[ADDR]]]
; r0 below is a reasonable guess but could change: it certainly comes into the
; function there.
-; CHECK-NEXT: uxth r[[OLDX:[0-9]+]], r[[OLD]]
-; CHECK-NEXT: cmp r[[OLDX]], r0
+; CHECK-NEXT: cmp r[[OLD]], r0
; CHECK-NEXT: bne .LBB{{[0-9]+}}_3
; CHECK-NEXT: BB#2:
; As above, r1 is a reasonable guess.
diff --git a/llvm/test/CodeGen/ARM/ldaex-stlex.ll b/llvm/test/CodeGen/ARM/ldaex-stlex.ll
index f309f77fd5f..bfdfea33156 100644
--- a/llvm/test/CodeGen/ARM/ldaex-stlex.ll
+++ b/llvm/test/CodeGen/ARM/ldaex-stlex.ll
@@ -34,17 +34,21 @@ declare i32 @llvm.arm.stlexd(i32, i32, i8*) nounwind
; CHECK-LABEL: test_load_i8:
; CHECK: ldaexb r0, [r0]
; CHECK-NOT: uxtb
-define i32 @test_load_i8(i8* %addr) {
+; CHECK-NOT: and
+define zeroext i8 @test_load_i8(i8* %addr) {
%val = call i32 @llvm.arm.ldaex.p0i8(i8* %addr)
- ret i32 %val
+ %val8 = trunc i32 %val to i8
+ ret i8 %val8
}
; CHECK-LABEL: test_load_i16:
; CHECK: ldaexh r0, [r0]
; CHECK-NOT: uxth
-define i32 @test_load_i16(i16* %addr) {
+; CHECK-NOT: and
+define zeroext i16 @test_load_i16(i16* %addr) {
%val = call i32 @llvm.arm.ldaex.p0i16(i16* %addr)
- ret i32 %val
+ %val16 = trunc i32 %val to i16
+ ret i16 %val16
}
; CHECK-LABEL: test_load_i32:
diff --git a/llvm/test/CodeGen/ARM/ldstrex.ll b/llvm/test/CodeGen/ARM/ldstrex.ll
index 5eaae53da99..a40e255e83e 100644
--- a/llvm/test/CodeGen/ARM/ldstrex.ll
+++ b/llvm/test/CodeGen/ARM/ldstrex.ll
@@ -36,17 +36,21 @@ declare i32 @llvm.arm.strexd(i32, i32, i8*) nounwind
; CHECK-LABEL: test_load_i8:
; CHECK: ldrexb r0, [r0]
; CHECK-NOT: uxtb
-define i32 @test_load_i8(i8* %addr) {
+; CHECK-NOT: and
+define zeroext i8 @test_load_i8(i8* %addr) {
%val = call i32 @llvm.arm.ldrex.p0i8(i8* %addr)
- ret i32 %val
+ %val8 = trunc i32 %val to i8
+ ret i8 %val8
}
; CHECK-LABEL: test_load_i16:
; CHECK: ldrexh r0, [r0]
; CHECK-NOT: uxth
-define i32 @test_load_i16(i16* %addr) {
+; CHECK-NOT: and
+define zeroext i16 @test_load_i16(i16* %addr) {
%val = call i32 @llvm.arm.ldrex.p0i16(i16* %addr)
- ret i32 %val
+ %val16 = trunc i32 %val to i16
+ ret i16 %val16
}
; CHECK-LABEL: test_load_i32:
@@ -137,3 +141,19 @@ define void @excl_addrmode() {
ret void
}
+
+; LLVM should know, even across basic blocks, that ldrex is setting the high
+; bits of its i32 to 0. There should be no zero-extend operation.
+define zeroext i8 @test_cross_block_zext_i8(i1 %tst, i8* %addr) {
+; CHECK: test_cross_block_zext_i8:
+; CHECK-NOT: uxtb
+; CHECK-NOT: and
+; CHECK: bx lr
+ %val = call i32 @llvm.arm.ldrex.p0i8(i8* %addr)
+ br i1 %tst, label %end, label %mid
+mid:
+ ret i8 42
+end:
+ %val8 = trunc i32 %val to i8
+ ret i8 %val8
+}
OpenPOWER on IntegriCloud