| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: opt -S -passes=inline %s | FileCheck %s |
| |
| declare float @val_f32() |
| declare float @use.val(float) willreturn nounwind |
| |
| define float @callee() { |
| ; CHECK-LABEL: define float @callee() { |
| ; CHECK-NEXT: [[R:%.*]] = call float @val_f32() |
| ; CHECK-NEXT: ret float [[R]] |
| ; |
| %r = call float @val_f32() |
| ret float %r |
| } |
| |
| define float @caller_okay_use_after_poison_anyways() { |
| ; CHECK-LABEL: define float @caller_okay_use_after_poison_anyways() { |
| ; CHECK-NEXT: [[R_I:%.*]] = call nofpclass(nan) float @val_f32() |
| ; CHECK-NEXT: call void @use.val(float [[R_I]]) |
| ; CHECK-NEXT: ret float [[R_I]] |
| ; |
| %r = call nofpclass(nan) float @callee() |
| call void @use.val(float %r) |
| ret float %r |
| } |
| |
| define float @callee_nofpclass_inf_nan() { |
| ; CHECK-LABEL: define float @callee_nofpclass_inf_nan() { |
| ; CHECK-NEXT: [[R:%.*]] = call nofpclass(nan inf) float @val_f32() |
| ; CHECK-NEXT: ret float [[R]] |
| ; |
| %r = call nofpclass(nan inf) float @val_f32() |
| ret float %r |
| } |
| |
| define float @caller_okay_intersect_nofpclass() { |
| ; CHECK-LABEL: define float @caller_okay_intersect_nofpclass() { |
| ; CHECK-NEXT: [[R_I:%.*]] = call nofpclass(nan inf) float @val_f32() |
| ; CHECK-NEXT: call void @use.val(float [[R_I]]) |
| ; CHECK-NEXT: ret float [[R_I]] |
| ; |
| %r = call nofpclass(nan) float @callee_nofpclass_inf_nan() |
| call void @use.val(float %r) |
| ret float %r |
| } |
| |
| define float @caller_not_intersecting_nofpclass() { |
| ; CHECK-LABEL: define float @caller_not_intersecting_nofpclass() { |
| ; CHECK-NEXT: [[R_I:%.*]] = call nofpclass(nan inf zero) float @val_f32() |
| ; CHECK-NEXT: call void @use.val(float [[R_I]]) |
| ; CHECK-NEXT: ret float [[R_I]] |
| ; |
| %r = call nofpclass(zero) float @callee_nofpclass_inf_nan() |
| call void @use.val(float %r) |
| ret float %r |
| } |
| |