Chromium Code Reviews| Index: test/Transforms/NaCl/expand-constantexpr.ll |
| diff --git a/test/Transforms/NaCl/expand-constantexpr.ll b/test/Transforms/NaCl/expand-constantexpr.ll |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..5ea26d86125d4db2e8e367762d864a32b76fc268 |
| --- /dev/null |
| +++ b/test/Transforms/NaCl/expand-constantexpr.ll |
| @@ -0,0 +1,97 @@ |
| +; RUN: opt < %s -expand-constant-expr -S | FileCheck %s |
| + |
| +@global_var1 = global i32 123 |
| +@global_var2 = global i32 123 |
| + |
| + |
| +define i8* @constantexpr_bitcast() { |
| + ret i8* bitcast (i32* @global_var1 to i8*) |
| +} |
| +; CHECK: @constantexpr_bitcast |
| +; CHECK: %expanded = bitcast i32* @global_var1 to i8* |
| +; CHECK: ret i8* %expanded |
| + |
| + |
| +define i32 @constantexpr_nested() { |
| + ret i32 add (i32 ptrtoint (i32* @global_var1 to i32), |
| + i32 ptrtoint (i32* @global_var2 to i32)) |
| +} |
| +; CHECK: @constantexpr_nested |
| +; CHECK: %expanded1 = ptrtoint i32* @global_var1 to i32 |
|
jvoung (off chromium)
2013/03/15 17:56:01
How about testing something with further nesting,
Mark Seaborn
2013/03/15 19:28:44
We're already testing some nesting, but OK, let's
|
| +; CHECK: %expanded2 = ptrtoint i32* @global_var2 to i32 |
| +; CHECK: %expanded = add i32 %expanded1, %expanded2 |
| +; CHECK: ret i32 %expanded |
| + |
| + |
| +define i32 @constantexpr_phi() { |
| +entry: |
| + br label %label |
| +label: |
| + %result = phi i32 [ ptrtoint (i32* @global_var1 to i32), %entry ] |
| + ret i32 %result |
| +} |
| +; CHECK: @constantexpr_phi |
| +; CHECK: entry: |
| +; CHECK: %expanded = ptrtoint i32* @global_var1 to i32 |
| +; CHECK: br label %label |
| +; CHECK: label: |
| +; CHECK: %result = phi i32 [ %expanded, %entry ] |
| + |
| + |
| +; This tests that ExpandConstantExpr correctly handles a PHI node that |
| +; contains the same ConstantExpr twice. |
| +; Using replaceAllUsesWith() is not correct on a PHI node when the |
| +; new instruction has to be added to an incoming block. |
| +define i32 @constantexpr_phi_twice(i1 %arg) { |
| + br i1 %arg, label %iftrue, label %iffalse |
| +iftrue: |
| + br label %exit |
| +iffalse: |
| + br label %exit |
| +exit: |
| + %result = phi i32 [ ptrtoint (i32* @global_var1 to i32), %iftrue ], |
| + [ ptrtoint (i32* @global_var1 to i32), %iffalse ] |
| + ret i32 %result |
| +} |
| +; CHECK: @constantexpr_phi_twice |
| +; CHECK: iftrue: |
| +; CHECK: %expanded = ptrtoint i32* @global_var1 to i32 |
| +; CHECK: iffalse: |
| +; CHECK: %expanded1 = ptrtoint i32* @global_var1 to i32 |
| +; CHECK: exit: |
| + |
| + |
| +define i32 @constantexpr_phi_multiple_entry(i1 %arg) { |
| +entry: |
| + br i1 %arg, label %done, label %done |
| +done: |
| + %result = phi i32 [ ptrtoint (i32* @global_var1 to i32), %entry ], |
|
jvoung (off chromium)
2013/03/15 17:56:01
Just curious: for an example which uses "br i1, ..
jvoung (off chromium)
2013/03/15 19:17:26
Err, n/m it only looks that way for this example b
Mark Seaborn
2013/03/15 19:28:44
This pass does generate the same evaluation orderi
|
| + [ ptrtoint (i32* @global_var1 to i32), %entry ] |
| + ret i32 %result |
| +} |
| +; CHECK: @constantexpr_phi_multiple_entry |
| +; CHECK: entry: |
| +; CHECK: %expanded = ptrtoint i32* @global_var1 to i32 |
| +; CHECK: br i1 %arg, label %done, label %done |
| +; CHECK: done: |
| +; CHECK: %result = phi i32 [ %expanded, %entry ], [ %expanded, %entry ] |
| + |
| + |
| + |
| +declare void @external_func() |
| +declare void @personality_func() |
| + |
| +define void @test_landingpad() { |
| + invoke void @external_func() to label %ok unwind label %onerror |
| +ok: |
| + ret void |
| +onerror: |
| + %lp = landingpad i32 |
| + personality i8* bitcast (void ()* @personality_func to i8*) |
| + catch i32* null |
| + ret void |
| +} |
| +; landingpad can only accept a ConstantExpr, so this should remain |
| +; unmodified. |
| +; CHECK: @test_landingpad |
| +; CHECK: personality i8* bitcast (void ()* @personality_func to i8*) |