This patch fixes a wrong constant folding of intrinsic 'convert.from.fp16'.
Function 'ConstantFoldScalarCall' (in ConstantFolding.cpp) works under the wrong assumption that a call to 'convert.from.fp16' always returns a value of type 'float'.
However, intrinsic 'convert.from.fp16' can be 'overloaded'; for example, we can use 'convert.from.fp16.fp64' to convert from half to double; etc.
Before this patch, the following example would have triggered an assertion failure in opt (with '-constprop'):
define double @foo() { entry: %0 = call double @llvm.convert.from.fp16.f64(i16 0) ret double %0 }
in Value.cpp:325: void llvm::Value::replaceAllUsesWith(llvm::Value*): Assertion `New->getType() == getType() && "replaceAllUses of value with new value of different type!" failed.
This patch fixes the problem in ConstantFolding.cpp. When folding a call to convert.from.fp16, we perform a different kind of conversion based on the call return type.
Added test 'Transform/ConstProp/convert-from-fp16.ll'.
Please let me know if ok to submit.
Thanks!
-Andrea
I swear I saw the same construct elsewhere, but I can't find it. Is there a good header where this could go?