grep did not use the output of ls in any way.
When you run grep f* in a situation where your shell expands f* to two or more arguments, grep considers all but one of them as names of files to open and read. When grep reads from named files, its default behavior of reading from standard input doesn't apply, so it doesn't read data piped to it from another command.
Your grep program is not broken, and the behavior you have observed is the correct and expected behavior, which is why reinstalling grep and rebooting did not change it. Details follow.
grep f* did not pass an argument of f* to grep.
grep never saw the text f*. As Soren A says, f* is a glob. Globs are treated specially by your shell. Because f* was not quoted, the shell expanded it into the names of files in the current directory that start with f. Each such name was passed to grep as a separate argument. (This kind of shell expansion is known variously as globbing, filename expansion, and pathname expansion.)
Based on your description, there are exactly two files that match the f* glob: file0.txt and file1.txt. Since those are the only two files in the current directory whose names start with f, the command-line arguments passed to grep from running grep f* are exactly the same as those passed to it from running grep file0.txt file1.txt. If you were to add more such files to the directory, then grep f* would pass more than those two filenames as arguments to grep, but file0.txt and file1.txt would still be included among them.
You piped ls output to grep, but grep did not read from the pipe.
A pipe connects the standard output of one command to the standard input of the other. Like cat and many other commands, grep accepts input in two ways:
- You can pass it filenames as command-line arguments, and it will read from those files. The first non-option argument to - grepis the pattern, but subsequent non-option arguments are treated as filenames from which input will be taken.
 - (You're not trying to pass multiple patterns to - grep, but if you were, you could use the- -eoption, whose operand is always treated as a pattern.)
 
- You can pass no filename arguments, and it will read from its own standard input. This is the situation in which it is effective to pipe to - grep. It is only in the absence of filename arguments that- grepreads from standard input at all.
 - This is why it's possible to use - grepto search one or more files, without it blocking and waiting for you to enter input into a terminal. When you pipe to- grep, the extra input that would make no sense for- grepto use comes from the command on the left side of the pipe rather than from your terminal.- grepstill doesn't use it, and this is a good thing.
 - (You're not trying to cause - grepto read standard input in addition to one or more named files, but if you were, you could pass it the- -argument.)
 
Because you have two files in the current directory whose names start with f, the glob f* expands to two arguments. The first, file0.txt, is used as the pattern. The second, file1.txt, is taken to name an input file. Because grep is given an argument specifying an input file, the first of the two situations described above applies ("You can pass it filenames as command-line arguments"). So grep never reads from standard input and never uses the output of ls.