Pretty much just copy pasted from noundef handling
Diff Detail
Event Timeline
Not familiar enough to assess if this covers everything. But LGTM. Might want to wait for comments from other reviewers.
LG
llvm/lib/Transforms/IPO/AttributorAttributes.cpp | ||
---|---|---|
10307 | This code doesn't seem to affect a test. call void @extern(%fp) willreturn nounwind ; < annotate this use call void @extern(nofpclass(nan inf) %fp) | |
10336 | You can add a test with an alloca if you want to verify it works not only through PHIs but also memory. |
llvm/test/Transforms/Attributor/nofpclass.ll | ||
---|---|---|
267 | If you introduce a block for the non-nan case you can use the value and instruction in the VisitValueCB to determine its non-nan. Only need to do that if the CtxI of the AA for the value is not the CtxI of the VisitValueCB though. |
llvm/lib/Transforms/IPO/AttributorAttributes.cpp | ||
---|---|---|
10307 | It also doesn't change this test | |
10336 | Like this? Doesn't work define float @returned_load(ptr %ptr) { ; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read) ; CHECK-LABEL: define float @returned_load ; CHECK-SAME: (ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[PTR:%.*]]) #[[ATTR4:[0-9]+]] { ; CHECK-NEXT: [[LOAD:%.*]] = load float, ptr [[PTR]], align 4 ; CHECK-NEXT: ret float [[LOAD]] ; %load = load float, ptr %ptr ret float %load } define float @pass_nofpclass_inf_through_memory(float nofpclass(inf) %arg) { ; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(none) ; TUNIT-LABEL: define float @pass_nofpclass_inf_through_memory ; TUNIT-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR2]] { ; TUNIT-NEXT: [[ALLOCA:%.*]] = alloca float, align 4 ; TUNIT-NEXT: store float [[ARG]], ptr [[ALLOCA]], align 4 ; TUNIT-NEXT: [[RET:%.*]] = call float @returned_load(ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ALLOCA]]) #[[ATTR7]] ; TUNIT-NEXT: ret float [[RET]] ; ; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(none) ; CGSCC-LABEL: define float @pass_nofpclass_inf_through_memory ; CGSCC-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: [[ALLOCA:%.*]] = alloca float, align 4 ; CGSCC-NEXT: store float [[ARG]], ptr [[ALLOCA]], align 4 ; CGSCC-NEXT: [[RET:%.*]] = call float @returned_load(ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ALLOCA]]) #[[ATTR6]] ; CGSCC-NEXT: ret float [[RET]] ; %alloca = alloca float store float %arg, ptr %alloca %ret = call float @returned_load(ptr %alloca) ret float %ret } |
llvm/test/Transforms/Attributor/nofpclass.ll | ||
---|---|---|
267 | I missed this comment initially and don't quite follow it |
This code doesn't seem to affect a test.
I think something like this should work now: