1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=instcombine %s | FileCheck %s 3 4; Treatment of operation with unused result. 5 6; If operation does not raise exceptions, it may be removed even in strict mode. 7define float @f_unused_precise() #0 { 8; CHECK-LABEL: @f_unused_precise( 9; CHECK-NEXT: entry: 10; CHECK-NEXT: ret float 1.000000e+00 11; 12entry: 13 %result = call float @llvm.experimental.constrained.fadd.f32(float 1.0, float 1.0, metadata !"round.upward", metadata !"fpexcept.strict") #0 14 ret float 1.0 15} 16 17; If operation raises exceptions, it cannot be removed in strict mode. 18define float @f_unused_strict() #0 { 19; CHECK-LABEL: @f_unused_strict( 20; CHECK-NEXT: entry: 21; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float 1.000000e+00, float 3.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0:[0-9]+]] 22; CHECK-NEXT: ret float 1.000000e+00 23; 24entry: 25 %result = call float @llvm.experimental.constrained.fdiv.f32(float 1.0, float 3.0, metadata !"round.tonearest", metadata !"fpexcept.strict") #0 26 ret float 1.0 27} 28 29; If operation raises exceptions, it can be removed in non-strict mode. 30define float @f_unused_ignore() #0 { 31; CHECK-LABEL: @f_unused_ignore( 32; CHECK-NEXT: entry: 33; CHECK-NEXT: ret float 1.000000e+00 34; 35entry: 36 %result = call float @llvm.experimental.constrained.fdiv.f32(float 1.0, float 3.0, metadata !"round.towardzero", metadata !"fpexcept.ignore") #0 37 ret float 1.0 38} 39 40; If operation raises exceptions, it can be removed in non-strict mode even if rounding mode is dynamic. 41define float @f_unused_dynamic_ignore() #0 { 42; CHECK-LABEL: @f_unused_dynamic_ignore( 43; CHECK-NEXT: entry: 44; CHECK-NEXT: ret float 1.000000e+00 45; 46entry: 47 %result = call float @llvm.experimental.constrained.fdiv.f32(float 1.0, float 3.0, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0 48 ret float 1.0 49} 50 51; If operation raises exceptions, it can be removed in "maytrap" mode. 52define float @f_unused_maytrap() #0 { 53; CHECK-LABEL: @f_unused_maytrap( 54; CHECK-NEXT: entry: 55; CHECK-NEXT: ret float 1.000000e+00 56; 57entry: 58 %result = call float @llvm.experimental.constrained.fdiv.f32(float 1.0, float 3.0, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0 59 ret float 1.0 60} 61 62; Constant evaluation. 63 64; If operation does not raise exceptions, it may be folded even in strict mode. 65define float @f_eval_precise() #0 { 66; CHECK-LABEL: @f_eval_precise( 67; CHECK-NEXT: entry: 68; CHECK-NEXT: ret float 2.000000e+00 69; 70entry: 71 %result = call float @llvm.experimental.constrained.fadd.f32(float 1.0, float 1.0, metadata !"round.upward", metadata !"fpexcept.strict") #0 72 ret float %result 73} 74 75; If operation raises exceptions, it cannot be folded in strict mode. 76define float @f_eval_strict() #0 { 77; CHECK-LABEL: @f_eval_strict( 78; CHECK-NEXT: entry: 79; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float 1.000000e+00, float 3.000000e+00, metadata !"round.upward", metadata !"fpexcept.strict") #[[ATTR0]] 80; CHECK-NEXT: ret float [[RESULT]] 81; 82entry: 83 %result = call float @llvm.experimental.constrained.fdiv.f32(float 1.0, float 3.0, metadata !"round.upward", metadata !"fpexcept.strict") #0 84 ret float %result 85} 86 87; If operation raises exceptions, it can be folded in non-strict mode. 88define float @f_eval_ignore() #0 { 89; CHECK-LABEL: @f_eval_ignore( 90; CHECK-NEXT: entry: 91; CHECK-NEXT: ret float 0x3FD5555540000000 92; 93entry: 94 %result = call float @llvm.experimental.constrained.fdiv.f32(float 1.0, float 3.0, metadata !"round.downward", metadata !"fpexcept.ignore") #0 95 ret float %result 96} 97 98; if result is imprecise, it cannot be folded if rounding mode is dynamic. 99define float @f_eval_dynamic_ignore() #0 { 100; CHECK-LABEL: @f_eval_dynamic_ignore( 101; CHECK-NEXT: entry: 102; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float 1.000000e+00, float 3.000000e+00, metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]] 103; CHECK-NEXT: ret float [[RESULT]] 104; 105entry: 106 %result = call float @llvm.experimental.constrained.fdiv.f32(float 1.0, float 3.0, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0 107 ret float %result 108} 109 110; If result is imprecise and rounding mode is not dynamic, operation can be folded in "maytrap" mode. 111define float @f_eval_maytrap() #0 { 112; CHECK-LABEL: @f_eval_maytrap( 113; CHECK-NEXT: entry: 114; CHECK-NEXT: ret float 0x3FD5555560000000 115; 116entry: 117 %result = call float @llvm.experimental.constrained.fdiv.f32(float 1.0, float 3.0, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0 118 ret float %result 119} 120 121 122declare float @llvm.experimental.constrained.fadd.f32(float, float, metadata, metadata) 123declare float @llvm.experimental.constrained.fdiv.f32(float, float, metadata, metadata) 124 125attributes #0 = { strictfp } 126