Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 ; RUN: opt < %s -expand-constant-expr -S | FileCheck %s | |
| 2 | |
| 3 @global_var1 = global i32 123 | |
| 4 @global_var2 = global i32 123 | |
| 5 | |
| 6 | |
| 7 define i8* @constantexpr_bitcast() { | |
| 8 ret i8* bitcast (i32* @global_var1 to i8*) | |
| 9 } | |
| 10 ; CHECK: @constantexpr_bitcast | |
| 11 ; CHECK: %expanded = bitcast i32* @global_var1 to i8* | |
| 12 ; CHECK: ret i8* %expanded | |
| 13 | |
| 14 | |
| 15 define i32 @constantexpr_nested() { | |
| 16 ret i32 add (i32 ptrtoint (i32* @global_var1 to i32), | |
| 17 i32 ptrtoint (i32* @global_var2 to i32)) | |
| 18 } | |
| 19 ; CHECK: @constantexpr_nested | |
| 20 ; 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
| |
| 21 ; CHECK: %expanded2 = ptrtoint i32* @global_var2 to i32 | |
| 22 ; CHECK: %expanded = add i32 %expanded1, %expanded2 | |
| 23 ; CHECK: ret i32 %expanded | |
| 24 | |
| 25 | |
| 26 define i32 @constantexpr_phi() { | |
| 27 entry: | |
| 28 br label %label | |
| 29 label: | |
| 30 %result = phi i32 [ ptrtoint (i32* @global_var1 to i32), %entry ] | |
| 31 ret i32 %result | |
| 32 } | |
| 33 ; CHECK: @constantexpr_phi | |
| 34 ; CHECK: entry: | |
| 35 ; CHECK: %expanded = ptrtoint i32* @global_var1 to i32 | |
| 36 ; CHECK: br label %label | |
| 37 ; CHECK: label: | |
| 38 ; CHECK: %result = phi i32 [ %expanded, %entry ] | |
| 39 | |
| 40 | |
| 41 ; This tests that ExpandConstantExpr correctly handles a PHI node that | |
| 42 ; contains the same ConstantExpr twice. | |
| 43 ; Using replaceAllUsesWith() is not correct on a PHI node when the | |
| 44 ; new instruction has to be added to an incoming block. | |
| 45 define i32 @constantexpr_phi_twice(i1 %arg) { | |
| 46 br i1 %arg, label %iftrue, label %iffalse | |
| 47 iftrue: | |
| 48 br label %exit | |
| 49 iffalse: | |
| 50 br label %exit | |
| 51 exit: | |
| 52 %result = phi i32 [ ptrtoint (i32* @global_var1 to i32), %iftrue ], | |
| 53 [ ptrtoint (i32* @global_var1 to i32), %iffalse ] | |
| 54 ret i32 %result | |
| 55 } | |
| 56 ; CHECK: @constantexpr_phi_twice | |
| 57 ; CHECK: iftrue: | |
| 58 ; CHECK: %expanded = ptrtoint i32* @global_var1 to i32 | |
| 59 ; CHECK: iffalse: | |
| 60 ; CHECK: %expanded1 = ptrtoint i32* @global_var1 to i32 | |
| 61 ; CHECK: exit: | |
| 62 | |
| 63 | |
| 64 define i32 @constantexpr_phi_multiple_entry(i1 %arg) { | |
| 65 entry: | |
| 66 br i1 %arg, label %done, label %done | |
| 67 done: | |
| 68 %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
| |
| 69 [ ptrtoint (i32* @global_var1 to i32), %entry ] | |
| 70 ret i32 %result | |
| 71 } | |
| 72 ; CHECK: @constantexpr_phi_multiple_entry | |
| 73 ; CHECK: entry: | |
| 74 ; CHECK: %expanded = ptrtoint i32* @global_var1 to i32 | |
| 75 ; CHECK: br i1 %arg, label %done, label %done | |
| 76 ; CHECK: done: | |
| 77 ; CHECK: %result = phi i32 [ %expanded, %entry ], [ %expanded, %entry ] | |
| 78 | |
| 79 | |
| 80 | |
| 81 declare void @external_func() | |
| 82 declare void @personality_func() | |
| 83 | |
| 84 define void @test_landingpad() { | |
| 85 invoke void @external_func() to label %ok unwind label %onerror | |
| 86 ok: | |
| 87 ret void | |
| 88 onerror: | |
| 89 %lp = landingpad i32 | |
| 90 personality i8* bitcast (void ()* @personality_func to i8*) | |
| 91 catch i32* null | |
| 92 ret void | |
| 93 } | |
| 94 ; landingpad can only accept a ConstantExpr, so this should remain | |
| 95 ; unmodified. | |
| 96 ; CHECK: @test_landingpad | |
| 97 ; CHECK: personality i8* bitcast (void ()* @personality_func to i8*) | |
| OLD | NEW |