1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2 3; Test function specialization wouldn't crash due to constant expression. 4; Note that this test case shows that function specialization pass would 5; transform the function even if no specialization happened. 6 7; RUN: opt -function-specialization -force-function-specialization -S < %s | FileCheck %s 8 9%struct = type { i8, i16, i32, i64, i64} 10@Global = internal constant %struct {i8 0, i16 1, i32 2, i64 3, i64 4} 11 12define internal i64 @zoo(i1 %flag) { 13; CHECK-LABEL: @zoo( 14; CHECK-NEXT: entry: 15; CHECK-NEXT: br i1 [[FLAG:%.*]], label [[PLUS:%.*]], label [[MINUS:%.*]] 16; CHECK: plus: 17; CHECK-NEXT: [[TMP0:%.*]] = call i64 @func2.1(i64* getelementptr inbounds ([[STRUCT:%.*]], %struct* @Global, i32 0, i32 3)) 18; CHECK-NEXT: br label [[MERGE:%.*]] 19; CHECK: minus: 20; CHECK-NEXT: [[TMP1:%.*]] = call i64 @func2.2(i64* getelementptr inbounds ([[STRUCT]], %struct* @Global, i32 0, i32 4)) 21; CHECK-NEXT: br label [[MERGE]] 22; CHECK: merge: 23; CHECK-NEXT: [[TMP2:%.*]] = phi i64 [ [[TMP0]], [[PLUS]] ], [ [[TMP1]], [[MINUS]] ] 24; CHECK-NEXT: ret i64 [[TMP2]] 25; 26entry: 27 br i1 %flag, label %plus, label %minus 28 29plus: 30 %arg = getelementptr %struct, %struct* @Global, i32 0, i32 3 31 %tmp0 = call i64 @func2(i64* %arg) 32 br label %merge 33 34minus: 35 %arg2 = getelementptr %struct, %struct* @Global, i32 0, i32 4 36 %tmp1 = call i64 @func2(i64* %arg2) 37 br label %merge 38 39merge: 40 %tmp2 = phi i64 [ %tmp0, %plus ], [ %tmp1, %minus] 41 ret i64 %tmp2 42} 43 44define internal i64 @func2(i64 *%x) { 45; CHECK-LABEL: @func2( 46; CHECK-NEXT: entry: 47; CHECK-NEXT: [[VAL:%.*]] = ptrtoint i64* [[X:%.*]] to i64 48; CHECK-NEXT: ret i64 [[VAL]] 49; 50entry: 51 %val = ptrtoint i64* %x to i64 52 ret i64 %val 53} 54 55define internal i64 @func(i64 *%x, i64 (i64*)* %binop) { 56; CHECK-LABEL: @func( 57; CHECK-NEXT: entry: 58; CHECK-NEXT: [[TMP0:%.*]] = call i64 [[BINOP:%.*]](i64* [[X:%.*]]) 59; CHECK-NEXT: ret i64 [[TMP0]] 60; 61entry: 62 %tmp0 = call i64 %binop(i64* %x) 63 ret i64 %tmp0 64} 65 66define i64 @main() { 67; CHECK-LABEL: @main( 68; CHECK-NEXT: [[TMP1:%.*]] = call i64 @zoo(i1 false) 69; CHECK-NEXT: [[TMP2:%.*]] = call i64 @zoo(i1 true) 70; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[TMP1]], [[TMP2]] 71; CHECK-NEXT: ret i64 [[TMP3]] 72; 73 %1 = call i64 @zoo(i1 0) 74 %2 = call i64 @zoo(i1 1) 75 %3 = add i64 %1, %2 76 ret i64 %3 77} 78 79; CHECK-LABEL: define internal i64 @func2.1( 80; CHECK-NEXT: entry: 81; CHECK-NEXT: ret i64 ptrtoint (i64* getelementptr inbounds (%struct, %struct* @Global, i32 0, i32 3) to i64) 82; CHECK-NEXT: } 83 84; CHECK-LABEL: define internal i64 @func2.2( 85; CHECK-NEXT: entry: 86; CHECK-NEXT: ret i64 ptrtoint (i64* getelementptr inbounds (%struct, %struct* @Global, i32 0, i32 4) to i64) 87; CHECK-NEXT: } 88