|  | ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs --version 5 | 
|  | ; RUN: opt -passes=print-predicateinfo -disable-output -S < %s 2>&1 | FileCheck %s --check-prefix=PREDINF | 
|  | ; RUN: opt -passes="ipsccp<func-spec>" -funcspec-min-function-size=1       \ | 
|  | ; RUN:                                 -funcspec-for-literal-constant=true \ | 
|  | ; RUN:                                 -funcspec-min-codesize-savings=50   \ | 
|  | ; RUN:                                 -funcspec-min-latency-savings=0     \ | 
|  | ; RUN:                                 -S < %s | FileCheck %s --check-prefix=FUNCSPEC | 
|  |  | 
|  | ; Verify that we are able to estimate the codesize savings by looking through | 
|  | ; calls to ssa_copy intrinsics, which are inserted by PredicateInfo when IPSCCP | 
|  | ; is run prior to FunctionSpecialization. | 
|  | define i32 @main() { | 
|  | entry: | 
|  | %res = call i32 @test_ssa_copy(i32 0) | 
|  | ret i32 %res | 
|  | } | 
|  |  | 
|  | define i32 @test_ssa_copy(i32 %x) { | 
|  | entry: | 
|  | br label %block1 | 
|  |  | 
|  | block1: | 
|  | %cmp = icmp eq i32 %x, 0 | 
|  | br i1 %cmp, label %block2, label %exit1 | 
|  |  | 
|  | block2: | 
|  | br i1 %cmp, label %block3, label %exit2 | 
|  |  | 
|  | block3: | 
|  | br i1 %cmp, label %exit4, label %exit3 | 
|  |  | 
|  | exit1: | 
|  | ret i32 %x | 
|  |  | 
|  | exit2: | 
|  | ret i32 %x | 
|  |  | 
|  | exit3: | 
|  | ret i32 %x | 
|  |  | 
|  | exit4: | 
|  | ret i32 999 | 
|  | } | 
|  | ; PREDINF-LABEL: define i32 @main() { | 
|  | ; PREDINF-NEXT:  [[ENTRY:.*:]] | 
|  | ; PREDINF-NEXT:    [[RES:%.*]] = call i32 @test_ssa_copy(i32 0) | 
|  | ; PREDINF-NEXT:    ret i32 [[RES]] | 
|  | ; | 
|  | ; | 
|  | ; PREDINF-LABEL: define i32 @test_ssa_copy( | 
|  | ; PREDINF-SAME: i32 [[X:%.*]]) { | 
|  | ; PREDINF-NEXT:  [[ENTRY:.*:]] | 
|  | ; PREDINF-NEXT:    br label %[[BLOCK1:.*]] | 
|  | ; PREDINF:       [[BLOCK1]]: | 
|  | ; PREDINF-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X]], 0 | 
|  | ; PREDINF:         [[CMP_0:%.*]] = bitcast i1 [[CMP]] to i1 | 
|  | ; PREDINF:         [[X_0:%.*]] = bitcast i32 [[X]] to i32 | 
|  | ; PREDINF:         [[X_4:%.*]] = bitcast i32 [[X]] to i32 | 
|  | ; PREDINF-NEXT:    br i1 [[CMP]], label %[[BLOCK2:.*]], label %[[EXIT1:.*]] | 
|  | ; PREDINF:       [[BLOCK2]]: | 
|  | ; PREDINF:         [[CMP_0_1:%.*]] = bitcast i1 [[CMP_0]] to i1 | 
|  | ; PREDINF:         [[X_0_1:%.*]] = bitcast i32 [[X_0]] to i32 | 
|  | ; PREDINF:         [[X_0_3:%.*]] = bitcast i32 [[X_0]] to i32 | 
|  | ; PREDINF-NEXT:    br i1 [[CMP_0]], label %[[BLOCK3:.*]], label %[[EXIT2:.*]] | 
|  | ; PREDINF:       [[BLOCK3]]: | 
|  | ; PREDINF:         [[X_0_1_2:%.*]] = bitcast i32 [[X_0_1]] to i32 | 
|  | ; PREDINF-NEXT:    br i1 [[CMP_0_1]], label %[[EXIT4:.*]], label %[[EXIT3:.*]] | 
|  | ; PREDINF:       [[EXIT1]]: | 
|  | ; PREDINF-NEXT:    ret i32 [[X_4]] | 
|  | ; PREDINF:       [[EXIT2]]: | 
|  | ; PREDINF-NEXT:    ret i32 [[X_0_3]] | 
|  | ; PREDINF:       [[EXIT3]]: | 
|  | ; PREDINF-NEXT:    ret i32 [[X_0_1_2]] | 
|  | ; PREDINF:       [[EXIT4]]: | 
|  | ; PREDINF-NEXT:    ret i32 999 | 
|  | ; | 
|  | ; | 
|  | ; FUNCSPEC-LABEL: define i32 @main() { | 
|  | ; FUNCSPEC-NEXT:  [[ENTRY:.*:]] | 
|  | ; FUNCSPEC-NEXT:    [[RES:%.*]] = call i32 @test_ssa_copy.specialized.1(i32 0) | 
|  | ; FUNCSPEC-NEXT:    ret i32 999 | 
|  | ; | 
|  | ; | 
|  | ; FUNCSPEC-LABEL: define range(i32 1, 0) i32 @test_ssa_copy( | 
|  | ; FUNCSPEC-SAME: i32 [[X:%.*]]) { | 
|  | ; FUNCSPEC-NEXT:  [[ENTRY:.*:]] | 
|  | ; FUNCSPEC-NEXT:    br label %[[BLOCK1:.*]] | 
|  | ; FUNCSPEC:       [[BLOCK1]]: | 
|  | ; FUNCSPEC-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X]], 0 | 
|  | ; FUNCSPEC-NEXT:    br i1 [[CMP]], label %[[BLOCK2:.*]], label %[[EXIT1:.*]] | 
|  | ; FUNCSPEC:       [[BLOCK2]]: | 
|  | ; FUNCSPEC-NEXT:    br label %[[BLOCK3:.*]] | 
|  | ; FUNCSPEC:       [[BLOCK3]]: | 
|  | ; FUNCSPEC-NEXT:    br label %[[EXIT4:.*]] | 
|  | ; FUNCSPEC:       [[EXIT1]]: | 
|  | ; FUNCSPEC-NEXT:    ret i32 [[X]] | 
|  | ; FUNCSPEC:       [[EXIT4]]: | 
|  | ; FUNCSPEC-NEXT:    ret i32 999 | 
|  | ; | 
|  | ; | 
|  | ; FUNCSPEC-LABEL: define internal i32 @test_ssa_copy.specialized.1( | 
|  | ; FUNCSPEC-SAME: i32 [[X:%.*]]) { | 
|  | ; FUNCSPEC-NEXT:  [[ENTRY:.*:]] | 
|  | ; FUNCSPEC-NEXT:    br label %[[BLOCK1:.*]] | 
|  | ; FUNCSPEC:       [[BLOCK1]]: | 
|  | ; FUNCSPEC-NEXT:    br label %[[BLOCK2:.*]] | 
|  | ; FUNCSPEC:       [[BLOCK2]]: | 
|  | ; FUNCSPEC-NEXT:    br label %[[BLOCK3:.*]] | 
|  | ; FUNCSPEC:       [[BLOCK3]]: | 
|  | ; FUNCSPEC-NEXT:    br label %[[EXIT4:.*]] | 
|  | ; FUNCSPEC:       [[EXIT4]]: | 
|  | ; FUNCSPEC-NEXT:    ret i32 poison | 
|  | ; |