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