Chromium Code Reviews| Index: test/NaCl/ARM/divrem-guards.ll |
| diff --git a/test/NaCl/ARM/divrem-guards.ll b/test/NaCl/ARM/divrem-guards.ll |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..1be08765c2ce6089cfecbae8cfae0a6c4a57396d |
| --- /dev/null |
| +++ b/test/NaCl/ARM/divrem-guards.ll |
| @@ -0,0 +1,107 @@ |
| +; RUN: llc -mtriple=armv7-unknown-nacl -sfi-branch -filetype=obj %s -o - \ |
|
eliben
2013/05/03 21:18:55
I wonder if there's a way to hook this pass to opt
sehr
2013/05/03 23:29:05
I have added an invocation under opt.
|
| +; RUN: | llvm-objdump -disassemble -triple armv7 -mattr=+nacl-trap - \ |
| +; RUN: | FileCheck %s |
| + |
| +; Check for all four operators that need guards. |
| +define i32 @mysdiv(i32 %x, i32 %y) #0 { |
| +entry: |
| + %x.addr = alloca i32, align 4 |
|
eliben
2013/05/03 21:18:55
Could you minimize this repeating test case to som
sehr
2013/05/03 23:29:05
Done.
|
| + %y.addr = alloca i32, align 4 |
| + store i32 %x, i32* %x.addr, align 4 |
| + store i32 %y, i32* %y.addr, align 4 |
| + %0 = load i32* %x.addr, align 4 |
|
Mark Seaborn
2013/05/03 21:25:36
Remove the loads+stores. You're copying Clang's -
sehr
2013/05/03 23:29:05
Yes, removed.
|
| + %1 = load i32* %y.addr, align 4 |
| + %div1 = sdiv i32 %0, %1 |
| +; CHECK: cmp r1, #0 |
|
Mark Seaborn
2013/05/03 21:25:36
It would be better to test at the IR level too. T
sehr
2013/05/03 23:29:05
I am now testing both ways.
sehr
2013/05/03 23:29:05
I am now checking both.
|
| +; CHECK-NEXT: beq |
|
eliben
2013/05/03 21:18:55
I'd check that a trap exists too, before the next
sehr
2013/05/03 23:29:05
Done.
|
| + ret i32 %div1 |
| +} |
| + |
| +define i32 @myudiv(i32 %x, i32 %y) #0 { |
| +entry: |
| + %x.addr = alloca i32, align 4 |
| + %y.addr = alloca i32, align 4 |
| + store i32 %x, i32* %x.addr, align 4 |
| + store i32 %y, i32* %y.addr, align 4 |
| + %0 = load i32* %x.addr, align 4 |
| + %1 = load i32* %y.addr, align 4 |
| + %div1 = udiv i32 %0, %1 |
| +; CHECK: cmp r1, #0 |
| +; CHECK-NEXT: beq |
| + ret i32 %div1 |
| +} |
| + |
| +define i32 @mysrem(i32 %x, i32 %y) #0 { |
| +entry: |
| + %x.addr = alloca i32, align 4 |
| + %y.addr = alloca i32, align 4 |
| + store i32 %x, i32* %x.addr, align 4 |
| + store i32 %y, i32* %y.addr, align 4 |
| + %0 = load i32* %x.addr, align 4 |
| + %1 = load i32* %y.addr, align 4 |
| + %rem1 = srem i32 %0, %1 |
| +; CHECK: cmp r1, #0 |
| +; CHECK-NEXT: beq |
| + ret i32 %rem1 |
| +} |
| + |
| +define i32 @myurem(i32 %x, i32 %y) #0 { |
| +entry: |
| + %x.addr = alloca i32, align 4 |
| + %y.addr = alloca i32, align 4 |
| + store i32 %x, i32* %x.addr, align 4 |
| + store i32 %y, i32* %y.addr, align 4 |
| + %0 = load i32* %x.addr, align 4 |
| + %1 = load i32* %y.addr, align 4 |
| + %rem1 = urem i32 %0, %1 |
| +; CHECK: cmp r1, #0 |
| +; CHECK-NEXT: beq |
| + ret i32 %rem1 |
| +} |
| + |
| +; Divides by non-zero constants should not be guarded. |
| +define i32 @mysdiv_const(i32 %x, i32 %y) #0 { |
| +entry: |
| + %x.addr = alloca i32, align 4 |
| + %y.addr = alloca i32, align 4 |
| + store i32 %x, i32* %x.addr, align 4 |
| + store i32 %y, i32* %y.addr, align 4 |
| + %0 = load i32* %x.addr, align 4 |
| + %div1 = sdiv i32 %0, 10 |
| +; CHECK-NOT: cmp r1, #0 |
| +; CHECK-NOT: f0 de fe e7 |
| + ret i32 %div1 |
| +} |
| + |
| +; Divides by explicit zero should prefixed by a trap. |
| +define i32 @mysdiv_zero(i32 %x, i32 %y) #0 { |
| +entry: |
| + %x.addr = alloca i32, align 4 |
| + %y.addr = alloca i32, align 4 |
| + store i32 %x, i32* %x.addr, align 4 |
| + store i32 %y, i32* %y.addr, align 4 |
| + %0 = load i32* %x.addr, align 4 |
| + %div1 = sdiv i32 %0, 0 |
| +; CHECK-NOT: cmp r1, #0 |
| +; CHECK: f0 de fe e7 |
| + ret i32 %div1 |
| +} |
| + |
| +; Divides at the start of block should be guarded correctly. |
| +define i32 @mysdiv_loop(i32 %x, i32 %y) #0 { |
| +entry: |
| + %x.addr = alloca i32, align 4 |
| + %y.addr = alloca i32, align 4 |
| + store i32 %x, i32* %x.addr, align 4 |
| + store i32 %y, i32* %y.addr, align 4 |
| + %0 = load i32* %x.addr, align 4 |
| + %1 = load i32* %y.addr, align 4 |
| + br label %header |
| +header: |
| + %div1 = sdiv i32 %0, %1 |
| +; CHECK: cmp r1, #0 |
| + br label %header |
| + ret i32 %div1 |
| +} |
| + |
| +attributes #0 = { nounwind } |