be more flexible in the fwrite(x, 0, y) -> NOP transformation
this gets rid of some false-positives, but not all as NewGVN does iterative
simplification of operands. To fully fix this we would need either a more
complicated encoding or a CEGAR-based approach.
MODIFY
llvm_util/known_fns.cpp
llvm_util/known_fns.cpp
@@ -174,14 +174,15 @@ known_call(llvm::CallInst &i, const llvm::TargetLibraryInfo &TLI,
case llvm::LibFunc_fwrite: {
auto size = getInt(*args[1]);
auto count = getInt(*args[2]);
- if (size && count) {
- auto bytes = *size * *count;
+ if (size || count) {
// size_t fwrite(const void *ptr, 0, 0, FILE *stream) -> 0
- if (bytes == 0)
+ if ((size && *size == 0) || (count && *count == 0))
RETURN_VAL(
make_unique<UnaryOp>(*ty, value_name(i),
*make_intconst(0, ty->bits()), UnaryOp::Copy));
-
+ }
+ if (size && count) {
+ auto bytes = *size * *count;
// (void)fwrite(const void *ptr, 1, 1, FILE *stream) ->
// (void)fputc(int c, FILE *stream))
if (bytes == 1 && i.use_empty() && TLI.has(llvm::LibFunc_fputc)) {

ADD
tests/alive-tv/calls/fwrite.srctgt.ll
+%FILE = type {}
+@empty = constant [0 x i8] zeroinitializer
+declare i64 @fwrite(i8*, i64, i64, %FILE*)
+
+define void @src(%FILE* %fp) {
+ %str = getelementptr inbounds [0 x i8], [0 x i8]* @empty, i64 0, i64 0
+ %1 = and i64 2122369476, 2066466721
+ %2 = call i64 @fwrite(i8* %str, i64 %1, i64 0, %FILE* %fp)
+ ret void
+}
+
+define void @tgt(%FILE* %fp) {
+ ret void
+}

be more flexible in the fwrite(x, 0, y) -> NOP transformation
this gets rid of some false-positives, but not all as NewGVN does iterative
simplification of operands. To fully fix this we would need either a more
complicated encoding or a CEGAR-based approach.