Since ToUpper would actually result in a new string being created, StringComparison.OrdinalIgnoreCase would be faster, also, regex has a lot of overhead for a simple compare like this. That said, String.IndexOf(String, StringComparison.OrdinalIgnoreCase) should be the fastest, since it does not involve creating new strings.
I would guess (there I go again) that RegEx has the better worst case because of how it evaluates the string, IndexOf will always do a linear search, I'm guessing (and again) that RegEx is using something a little better. RegEx should also have a best case which would likely be close, though not as good, as IndexOf (due to additional complexity in it's language).
You peaked my curiousity (15,000 length string, 10,000 loop):
IndexOf-OrdinalIgnoreCase 00:00:00.0156251
RegEx-IgnoreCase 00:00:00.1093757
IndexOf-ToUpper 00:00:00.9531311
IndexOf-ToLower 00:00:00.9531311
Placement in the string also makes a huge difference:
At start:
Match00:00:00.6250040
IndexOf00:00:00.0156251
ToUpper00:00:00.9687562
ToLower00:00:01.0000064
At End:
Match00:00:00.5781287
IndexOf00:00:01.0468817
ToUpper00:00:01.4062590
ToLower00:00:01.4218841
Not Found:
Match00:00:00.5625036
IndexOf00:00:01.0000064
ToUpper00:00:01.3750088
ToLower00:00:01.3906339