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 |
| 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_nested2() { |
| 27 ret i32 mul (i32 add (i32 ptrtoint (i32* @global_var1 to i32), |
| 28 i32 ptrtoint (i32* @global_var2 to i32)), i32 2) |
| 29 } |
| 30 ; CHECK: @constantexpr_nested2 |
| 31 ; CHECK: %expanded2 = ptrtoint i32* @global_var1 to i32 |
| 32 ; CHECK: %expanded3 = ptrtoint i32* @global_var2 to i32 |
| 33 ; CHECK: %expanded1 = add i32 %expanded2, %expanded3 |
| 34 ; CHECK: %expanded = mul i32 %expanded1, 2 |
| 35 ; CHECK: ret i32 %expanded |
| 36 |
| 37 |
| 38 define i32 @constantexpr_phi() { |
| 39 entry: |
| 40 br label %label |
| 41 label: |
| 42 %result = phi i32 [ ptrtoint (i32* @global_var1 to i32), %entry ] |
| 43 ret i32 %result |
| 44 } |
| 45 ; CHECK: @constantexpr_phi |
| 46 ; CHECK: entry: |
| 47 ; CHECK: %expanded = ptrtoint i32* @global_var1 to i32 |
| 48 ; CHECK: br label %label |
| 49 ; CHECK: label: |
| 50 ; CHECK: %result = phi i32 [ %expanded, %entry ] |
| 51 |
| 52 |
| 53 ; This tests that ExpandConstantExpr correctly handles a PHI node that |
| 54 ; contains the same ConstantExpr twice. |
| 55 ; Using replaceAllUsesWith() is not correct on a PHI node when the |
| 56 ; new instruction has to be added to an incoming block. |
| 57 define i32 @constantexpr_phi_twice(i1 %arg) { |
| 58 br i1 %arg, label %iftrue, label %iffalse |
| 59 iftrue: |
| 60 br label %exit |
| 61 iffalse: |
| 62 br label %exit |
| 63 exit: |
| 64 %result = phi i32 [ ptrtoint (i32* @global_var1 to i32), %iftrue ], |
| 65 [ ptrtoint (i32* @global_var1 to i32), %iffalse ] |
| 66 ret i32 %result |
| 67 } |
| 68 ; CHECK: @constantexpr_phi_twice |
| 69 ; CHECK: iftrue: |
| 70 ; CHECK: %expanded = ptrtoint i32* @global_var1 to i32 |
| 71 ; CHECK: iffalse: |
| 72 ; CHECK: %expanded1 = ptrtoint i32* @global_var1 to i32 |
| 73 ; CHECK: exit: |
| 74 |
| 75 |
| 76 define i32 @constantexpr_phi_multiple_entry(i1 %arg) { |
| 77 entry: |
| 78 br i1 %arg, label %done, label %done |
| 79 done: |
| 80 %result = phi i32 [ ptrtoint (i32* @global_var1 to i32), %entry ], |
| 81 [ ptrtoint (i32* @global_var1 to i32), %entry ] |
| 82 ret i32 %result |
| 83 } |
| 84 ; CHECK: @constantexpr_phi_multiple_entry |
| 85 ; CHECK: entry: |
| 86 ; CHECK: %expanded = ptrtoint i32* @global_var1 to i32 |
| 87 ; CHECK: br i1 %arg, label %done, label %done |
| 88 ; CHECK: done: |
| 89 ; CHECK: %result = phi i32 [ %expanded, %entry ], [ %expanded, %entry ] |
| 90 |
| 91 |
| 92 |
| 93 declare void @external_func() |
| 94 declare void @personality_func() |
| 95 |
| 96 define void @test_landingpad() { |
| 97 invoke void @external_func() to label %ok unwind label %onerror |
| 98 ok: |
| 99 ret void |
| 100 onerror: |
| 101 %lp = landingpad i32 |
| 102 personality i8* bitcast (void ()* @personality_func to i8*) |
| 103 catch i32* null |
| 104 ret void |
| 105 } |
| 106 ; landingpad can only accept a ConstantExpr, so this should remain |
| 107 ; unmodified. |
| 108 ; CHECK: @test_landingpad |
| 109 ; CHECK: personality i8* bitcast (void ()* @personality_func to i8*) |
OLD | NEW |