1// RUN: tco %s | FileCheck %s 2// RUN: %flang_fc1 -emit-llvm %s -o - | FileCheck %s 3 4// Test peephole optimizations 5 6// CHECK-LABEL: define i8 @test_trunc( 7// CHECK-SAME: i256 %[[arg:.*]]) 8// CHECK-NEXT: = trunc i256 %[[arg]] to i8 9// CHECK-NEXT: ret i8 10func.func @test_trunc(%0 : i256) -> i8 { 11 %1 = fir.convert %0 : (i256) -> i128 12 %2 = fir.convert %1 : (i128) -> i64 13 %3 = fir.convert %2 : (i64) -> i32 14 %4 = fir.convert %3 : (i32) -> i16 15 %5 = fir.convert %4 : (i16) -> i8 16 return %5 : i8 17} 18 19// CHECK-LABEL: define i256 @test_sext( 20// CHECK-SAME: i8 %[[arg:.*]]) 21// CHECK-NEXT: = sext i8 %[[arg]] to i256 22// CHECK-NEXT: ret i256 23func.func @test_sext(%0 : i8) -> i256 { 24 %1 = fir.convert %0 : (i8) -> i16 25 %2 = fir.convert %1 : (i16) -> i32 26 %3 = fir.convert %2 : (i32) -> i64 27 %4 = fir.convert %3 : (i64) -> i128 28 %5 = fir.convert %4 : (i128) -> i256 29 return %5 : i256 30} 31 32// CHECK-LABEL: define half @test_fptrunc( 33// CHECK-SAME: fp128 %[[arg:.*]]) 34// CHECK-NEXT: %[[res:.*]] = fptrunc fp128 %[[arg]] to half 35// CHECK-NEXT: ret half %[[res]] 36func.func @test_fptrunc(%0 : f128) -> f16 { 37 %2 = fir.convert %0 : (f128) -> f64 38 %3 = fir.convert %2 : (f64) -> f32 39 %4 = fir.convert %3 : (f32) -> f16 40 return %4 : f16 41} 42 43// CHECK-LABEL: define x86_fp80 @test_fpext( 44// CHECK-SAME: bfloat %[[arg:.*]]) 45// CHECK-NEXT: = fpext bfloat %[[arg]] to x86_fp80 46// CHECK-NEXT: ret x86_fp80 47func.func @test_fpext(%0 : bf16) -> f80 { 48 %2 = fir.convert %0 : (bf16) -> f32 49 %3 = fir.convert %2 : (f32) -> f64 50 %4 = fir.convert %3 : (f64) -> f80 51 return %4 : f80 52} 53 54// CHECK-LABEL: define i64 @test_ascending( 55// CHECK-SAME: i8 %[[arg:.*]]) 56// CHECK-NEXT: = sext i8 %[[arg]] to i64 57// CHECK-NEXT: ret i64 58func.func @test_ascending(%0 : i8) -> index { 59 %1 = fir.convert %0 : (i8) -> i16 60 %2 = fir.convert %1 : (i16) -> i32 61 %3 = fir.convert %2 : (i32) -> i64 62 %5 = fir.convert %3 : (i64) -> index 63 return %5 : index 64} 65 66// CHECK-LABEL: define i8 @test_descending( 67// CHECK-SAME: i64 %[[arg:.*]]) 68// CHECK-NEXT: = trunc i64 %[[arg]] to i8 69// CHECK-NEXT: ret i8 70func.func @test_descending(%0 : index) -> i8 { 71 %2 = fir.convert %0 : (index) -> i64 72 %3 = fir.convert %2 : (i64) -> i32 73 %4 = fir.convert %3 : (i32) -> i16 74 %5 = fir.convert %4 : (i16) -> i8 75 return %5 : i8 76} 77 78// CHECK-LABEL: define float @test_useless( 79// CHECK-SAME: float %[[arg:.*]]) 80// CHECK-NEXT: ret float %[[arg]] 81func.func @test_useless(%0 : f32) -> f32 { 82 %1 = fir.convert %0 : (f32) -> f32 83 return %1 : f32 84} 85 86// CHECK-LABEL: define float @test_useless_sext( 87// CHECK-SAME: i32 %[[arg:.*]]) 88// CHECK-NEXT: %[[res:.*]] = sitofp i32 %[[arg]] to float 89// CHECK-NEXT: ret float %[[res]] 90func.func @test_useless_sext(%0 : i32) -> f32 { 91 %1 = fir.convert %0 : (i32) -> i64 92 %2 = fir.convert %1 : (i64) -> i32 93 %3 = fir.convert %2 : (i32) -> f32 94 return %3 : f32 95} 96 97// CHECK-LABEL: define i16 @test_hump( 98// CHECK-SAME: i32 %[[arg:.*]]) 99// CHECK-NEXT: trunc i32 %[[arg]] to i16 100// CHECK-NEXT: ret i16 101func.func @test_hump(%0 : i32) -> i16 { 102 %1 = fir.convert %0 : (i32) -> i64 103 %2 = fir.convert %1 : (i64) -> i16 104 return %2 : i16 105} 106 107// CHECK-LABEL: define i16 @test_slump( 108// CHECK-SAME: i32 %[[arg:.*]]) 109// CHECK-NEXT: %[[i:.*]] = trunc i32 %[[arg]] to i8 110// CHECK-NEXT: sext i8 %[[i]] to i16 111// CHECK-NEXT: ret i16 112func.func @test_slump(%0 : i32) -> i16 { 113 %1 = fir.convert %0 : (i32) -> i8 114 %2 = fir.convert %1 : (i8) -> i16 115 return %2 : i16 116} 117 118// CHECK-LABEL: define i64 @test_slump2( 119// CHECK-SAME: i64 %[[arg:.*]]) 120// CHECK-NEXT: %[[i:.*]] = trunc i64 %[[arg]] to i16 121// CHECK-NEXT: sext i16 %[[i]] to i64 122// CHECK-NEXT: ret i64 123func.func @test_slump2(%0 : index) -> index { 124 %1 = fir.convert %0 : (index) -> i16 125 %2 = fir.convert %1 : (i16) -> index 126 return %2 : index 127} 128