1; RUN: llvm-dis -expand-constant-exprs < %s.bc | FileCheck %s 2 3@g = extern_weak global i32 4@g2 = extern_weak global i32 5 6define i64 @test_cast() { 7; CHECK-LABEL: define i64 @test_cast() { 8; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64 9; CHECK-NEXT: ret i64 %constexpr 10 ret i64 ptrtoint (ptr @g to i64) 11} 12 13define i1 @test_icmp() { 14; CHECK-LABEL: define i1 @test_icmp() { 15; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64 16; CHECK-NEXT: %constexpr1 = icmp ne i64 %constexpr, 0 17; CHECK-NEXT: ret i1 %constexpr1 18 ret i1 icmp ne (i64 ptrtoint (ptr @g to i64), i64 0) 19} 20 21define i32 @test_select() { 22; CHECK-LABEL: define i32 @test_select() { 23; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64 24; CHECK-NEXT: %constexpr1 = icmp ne i64 %constexpr, 0 25; CHECK-NEXT: %constexpr2 = select i1 %constexpr1, i32 1, i32 2 26; CHECK-NEXT: ret i32 %constexpr2 27 ret i32 select (i1 icmp ne (i64 ptrtoint (ptr @g to i64), i64 0), i32 1, i32 2) 28} 29 30define i8 @test_extractelement() { 31; CHECK-LABEL: define i8 @test_extractelement() { 32; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64 33; CHECK-NEXT: %constexpr1 = icmp ne i64 %constexpr, 0 34; CHECK-NEXT: %constexpr2 = select i1 %constexpr1, <2 x i8> zeroinitializer, <2 x i8> <i8 0, i8 1> 35; CHECK-NEXT: %constexpr3 = extractelement <2 x i8> %constexpr2, i32 0 36; CHECK-NEXT: ret i8 %constexpr3 37 ret i8 extractelement (<2 x i8> select (i1 icmp ne (i64 ptrtoint (ptr @g to i64), i64 0), <2 x i8> zeroinitializer, <2 x i8> <i8 0, i8 1>), i32 0) 38} 39 40define <2 x i8> @test_insertelement() { 41; CHECK-LABEL: define <2 x i8> @test_insertelement() { 42; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i32 43; CHECK-NEXT: %constexpr1 = insertelement <2 x i8> poison, i8 42, i32 %constexpr 44; CHECK-NEXT: ret <2 x i8> %constexpr1 45 ret <2 x i8> insertelement (<2 x i8> poison, i8 42, i32 ptrtoint (ptr @g to i32)) 46} 47 48define double @test_fneg() { 49; CHECK-LABEL: define double @test_fneg() { 50; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64 51; CHECK-NEXT: %constexpr1 = bitcast i64 %constexpr to double 52; CHECK-NEXT: %constexpr2 = fneg double %constexpr1 53 ret double fneg (double bitcast (i64 ptrtoint (ptr @g to i64) to double)) 54} 55 56define i64 @test_flags() { 57; CHECK-LABEL: define i64 @test_flags() { 58; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64 59; CHECK-NEXT: %constexpr1 = add nuw i64 %constexpr, 1 60; CHECK-NEXT: ret i64 %constexpr1 61 ret i64 add nuw (i64 ptrtoint (ptr @g to i64), i64 1) 62} 63 64define <3 x i64> @test_vector() { 65; CHECK-LABEL: define <3 x i64> @test_vector() { 66; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64 67; CHECK-NEXT: %constexpr.ins = insertelement <3 x i64> poison, i64 5, i32 0 68; CHECK-NEXT: %constexpr.ins1 = insertelement <3 x i64> %constexpr.ins, i64 %constexpr, i32 1 69; CHECK-NEXT: %constexpr.ins2 = insertelement <3 x i64> %constexpr.ins1, i64 7, i32 2 70 ret <3 x i64> <i64 5, i64 ptrtoint (ptr @g to i64), i64 7> 71} 72 73define [3 x i64] @test_array() { 74; CHECK-LABEL: define [3 x i64] @test_array() { 75; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64 76; CHECK-NEXT: %constexpr.ins = insertvalue [3 x i64] poison, i64 5, 0 77; CHECK-NEXT: %constexpr.ins1 = insertvalue [3 x i64] %constexpr.ins, i64 %constexpr, 1 78; CHECK-NEXT: %constexpr.ins2 = insertvalue [3 x i64] %constexpr.ins1, i64 7, 2 79 ret [3 x i64] [i64 5, i64 ptrtoint (ptr @g to i64), i64 7] 80} 81 82define { i64, i64, i64 } @test_struct() { 83; CHECK-LABEL: define { i64, i64, i64 } @test_struct() { 84; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64 85; CHECK-NEXT: %constexpr.ins = insertvalue { i64, i64, i64 } poison, i64 5, 0 86; CHECK-NEXT: %constexpr.ins1 = insertvalue { i64, i64, i64 } %constexpr.ins, i64 %constexpr, 1 87; CHECK-NEXT: %constexpr.ins2 = insertvalue { i64, i64, i64 } %constexpr.ins1, i64 7, 2 88 ret { i64, i64, i64 } {i64 5, i64 ptrtoint (ptr @g to i64), i64 7} 89} 90 91define i64 @test_reused_expr() { 92; CHECK-LABEL: define i64 @test_reused_expr() { 93; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64 94; CHECK-NEXT: %constexpr1 = add i64 %constexpr, %constexpr 95; CHECK-NEXT: ret i64 %constexpr1 96 ret i64 add (i64 ptrtoint (ptr @g to i64), i64 ptrtoint (ptr @g to i64)) 97} 98 99define i64 @test_multiple_expanded_operands() { 100; CHECK-LABEL: define i64 @test_multiple_expanded_operands() { 101; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64 102; CHECK-NEXT: %constexpr1 = ptrtoint ptr @g2 to i64 103; CHECK-NEXT: %constexpr2 = add i64 %constexpr, %constexpr1 104; CHECK-NEXT: ret i64 %constexpr2 105 ret i64 add (i64 ptrtoint (ptr @g to i64), i64 ptrtoint (ptr @g2 to i64)) 106} 107 108define i64 @test_mid_block(i64 %arg) { 109; CHECK-LABEL: define i64 @test_mid_block(i64 %arg) { 110; CHECK-NEXT: %x = mul i64 %arg, 3 111; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64 112; CHECK-NEXT: %add = add i64 %x, %constexpr 113; CHECK-NEXT: ret i64 %add 114 %x = mul i64 %arg, 3 115 %add = add i64 %x, ptrtoint (ptr @g to i64) 116 ret i64 %add 117} 118 119define i64 @test_phi_non_critical_edge_block_before(i1 %c) { 120; CHECK-LABEL: define i64 @test_phi_non_critical_edge_block_before(i1 %c) { 121; CHECK: entry: 122; CHECK-NEXT: br i1 %c, label %if, label %join 123; CHECK: if: 124; CHECK-NEXT: br label %phi.constexpr 125; CHECK: phi.constexpr: 126; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64 127; CHECK-NEXT: br label %join 128; CHECK: join: 129; CHECK-NEXT: %phi = phi i64 [ 0, %entry ], [ %constexpr, %phi.constexpr ] 130; CHECK-NEXT: ret i64 %phi 131entry: 132 br i1 %c, label %if, label %join 133 134if: 135 br label %join 136 137join: 138 %phi = phi i64 [ 0, %entry ], [ ptrtoint (ptr @g to i64), %if ] 139 ret i64 %phi 140} 141 142define i64 @test_phi_non_critical_edge_block_after(i1 %c) { 143; CHECK-LABEL: define i64 @test_phi_non_critical_edge_block_after(i1 %c) { 144; CHECK: entry: 145; CHECK-NEXT: br i1 %c, label %if, label %join 146; CHECK: phi.constexpr: 147; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64 148; CHECK-NEXT: br label %join 149; CHECK: join: 150; CHECK-NEXT: %phi = phi i64 [ 0, %entry ], [ %constexpr, %phi.constexpr ] 151; CHECK-NEXT: ret i64 %phi 152; CHECK: if: 153; CHECK-NEXT: br label %phi.constexpr 154entry: 155 br i1 %c, label %if, label %join 156 157join: 158 %phi = phi i64 [ 0, %entry ], [ ptrtoint (ptr @g to i64), %if ] 159 ret i64 %phi 160 161if: 162 br label %join 163} 164 165define i64 @test_phi_critical_edge(i1 %c) { 166; CHECK-LABEL: define i64 @test_phi_critical_edge(i1 %c) { 167; CHECK: entry: 168; CHECK-NEXT: br i1 %c, label %if, label %phi.constexpr 169; CHECK: if: 170; CHECK-NEXT: br label %join 171; CHECK: phi.constexpr: 172; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64 173; CHECK-NEXT: br label %join 174; CHECK: join: 175; CHECK-NEXT: %phi = phi i64 [ %constexpr, %phi.constexpr ], [ 0, %if ] 176; CHECK-NEXT: ret i64 %phi 177entry: 178 br i1 %c, label %if, label %join 179 180if: 181 br label %join 182 183join: 184 %phi = phi i64 [ ptrtoint (ptr @g to i64), %entry ], [ 0, %if ] 185 ret i64 %phi 186} 187 188define i64 @test_phi_multiple_nodes(i1 %c) { 189; CHECK-LABEL: define i64 @test_phi_multiple_nodes(i1 %c) { 190; CHECK: entry: 191; CHECK-NEXT: br i1 %c, label %if, label %join 192; CHECK: if: 193; CHECK-NEXT: br label %phi.constexpr 194; CHECK: phi.constexpr: 195; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64 196; CHECK-NEXT: %constexpr2 = ptrtoint ptr @g2 to i64 197; CHECK-NEXT: br label %join 198; CHECK: join: 199; CHECK-NEXT: %phi = phi i64 [ 0, %entry ], [ %constexpr, %phi.constexpr ] 200; CHECK-NEXT: %phi2 = phi i64 [ 0, %entry ], [ %constexpr2, %phi.constexpr ] 201; CHECK-NEXT: ret i64 %phi 202entry: 203 br i1 %c, label %if, label %join 204 205if: 206 br label %join 207 208join: 209 %phi = phi i64 [ 0, %entry ], [ ptrtoint (ptr @g to i64), %if ] 210 %phi2 = phi i64 [ 0, %entry ], [ ptrtoint (ptr @g2 to i64), %if ] 211 ret i64 %phi 212} 213 214 215define i64 @test_phi_multiple_identical_predecessors(i32 %x) { 216; CHECK-LABEL: define i64 @test_phi_multiple_identical_predecessors(i32 %x) { 217; CHECK: entry: 218; CHECK-NEXT: switch i32 %x, label %default [ 219; CHECK-NEXT: i32 0, label %phi.constexpr 220; CHECK-NEXT: i32 1, label %phi.constexpr 221; CHECK-NEXT: ] 222; CHECK: default: 223; CHECK-NEXT: br label %join 224; CHECK: phi.constexpr: 225; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64 226; CHECK-NEXT: br label %join 227; CHECK: join: 228; CHECK-NEXT: %phi = phi i64 [ %constexpr, %phi.constexpr ], [ %constexpr, %phi.constexpr ], [ 0, %default ] 229; CHECK-NEXT: ret i64 %phi 230entry: 231 switch i32 %x, label %default [ 232 i32 0, label %join 233 i32 1, label %join 234 ] 235 236default: 237 br label %join 238 239join: 240 %phi = phi i64 [ ptrtoint (ptr @g to i64), %entry ], [ ptrtoint (ptr @g to i64), %entry ], [ 0, %default ] 241 ret i64 %phi 242} 243