This is an archive of the discontinued LLVM Phabricator instance.

X86: Don't emit SAHF/LAHF for 64-bit targets unless explicitly supported
ClosedPublic

Authored by hans on Dec 4 2015, 11:42 AM.

Details

Summary

These instructions are not supported by all CPUs in 64-bit mode. Emitting them causes Chromium to crash on start-up for users with those chips.

(GCC puts this behind -msahf on 64-bit for the same reason.)

This patch adds FeatureSAHF, enables it by default for 32-bit targets and modern CPUs, and changes X86InstrInfo::copyPhysReg back to the lowering from before r244503 when it's not available.

I'm not familiar with all the x86 CPU models, but I believe the ones I updated are all modern enough.

Please take a look.

Diff Detail

Repository
rL LLVM

Event Timeline

hans updated this revision to Diff 41901.Dec 4 2015, 11:42 AM
hans retitled this revision from to X86: Don't emit SAHF/LAHF for 64-bit targets unless explicitly supported.
hans updated this object.
hans added reviewers: jfb, majnemer, eliben, rnk.
hans added subscribers: llvm-commits, thakis.
jfb edited edge metadata.Dec 4 2015, 11:47 AM

Looks like we raced: D15239!

majnemer added inline comments.Dec 4 2015, 11:53 AM
lib/Target/X86/X86Subtarget.cpp
192–202 ↗(On Diff #41901)

Looks like some debugging code was left around?

jfb added a comment.Dec 4 2015, 11:54 AM

I haven't looked through the list of CPU support, or tests yet.

lib/Target/X86/X86.td
186 ↗(On Diff #41901)

I like my naming of HasLAHFSAHF since it's more comprehensive.

lib/Target/X86/X86ISelLowering.cpp
13935 ↗(On Diff #41901)

This should be fixed before committing?

lib/Target/X86/X86InstrInfo.cpp
4468 ↗(On Diff #41901)

I like my format for lib/Target/X86/X86InstrInfo.cpp in D15239 better ☺

lib/Target/X86/X86Subtarget.cpp
200 ↗(On Diff #41901)

What name does GCC use?

majnemer added inline comments.Dec 4 2015, 12:24 PM
lib/Target/X86/X86Subtarget.cpp
200 ↗(On Diff #41901)
hans added a comment.Dec 4 2015, 12:58 PM

Thanks for the quick review!

lib/Target/X86/X86.td
186 ↗(On Diff #41901)

Renamed.

I would like to keep the "sahf" name though, to match gcc's -msahf flag.

lib/Target/X86/X86ISelLowering.cpp
13935 ↗(On Diff #41901)

No, there is nothing to be fixed. 64-bit targets all have FCOMI, so we shouldn't be emitting SAHF for 64-bit here, and the assert shouldn't fire.

lib/Target/X86/X86InstrInfo.cpp
4468 ↗(On Diff #41901)

It does look nicer :-)

lib/Target/X86/X86Subtarget.cpp
192–202 ↗(On Diff #41901)

Oops. That should teach me to rush things out before lunch :-)

hans updated this revision to Diff 41930.Dec 4 2015, 12:58 PM
hans edited edge metadata.

Addressing comments.

jfb added a comment.Dec 4 2015, 1:21 PM

Looks good overall, though I haven't validated the list of supported CPUs. How did you create it?

hans added a comment.Dec 4 2015, 1:25 PM
In D15240#302911, @jfb wrote:

Looks good overall, though I haven't validated the list of supported CPUs. How did you create it?

I added the feature to all the architectures which seemed (by looking at Wikipedia) significantly newer than 2005. It's probably not an exhaustive list, but I believe it's conservatively correct.

jfb added a comment.Dec 4 2015, 1:57 PM

Could you rebase the change? You're missing my recent patch which slightly conflicts.

hans updated this revision to Diff 41939.Dec 4 2015, 2:23 PM

Rebase.

jfb accepted this revision.Dec 4 2015, 2:51 PM
jfb edited edge metadata.

Sorry, a few more comments. lgtm otherwise.

lib/Target/X86/X86.td
564 ↗(On Diff #41939)

Looks like the above two should also have lahf/sahf.

lib/Target/X86/X86InstrInfo.cpp
4398 ↗(On Diff #41939)

IIUC you can assert(is64); here?

This revision is now accepted and ready to land.Dec 4 2015, 2:51 PM
This revision was automatically updated to reflect the committed changes.
hans marked 2 inline comments as done.
jfb added inline comments.Dec 4 2015, 3:16 PM
llvm/trunk/lib/Target/X86/X86.td
561

I think this one could have it as well?

hans added inline comments.Dec 4 2015, 3:35 PM
llvm/trunk/lib/Target/X86/X86.td
561

Sorry, I missed the "above *two*" part of your previous comment. Added in r254801.

@jfb, this brings back the issue we solved with http://reviews.llvm.org/D6629. We can't issue PUSHFQ/POPFQ as the POPFQ can corrupt EFLAGS by loading a stale value.

jfb added a comment.Jan 20 2016, 8:19 PM

@jfb, this brings back the issue we solved with http://reviews.llvm.org/D6629. We can't issue PUSHFQ/POPFQ as the POPFQ can corrupt EFLAGS by loading a stale value.

Agreed, you'll need to compile with -mattr=+sahf to avoid that issue.

We could also teach LLVM to be smarter about flags, but that's quite a bit more work that we've already poured into this!

In D15240#332004, @jfb wrote:

Agreed, you'll need to compile with -mattr=+sahf to avoid that issue.

Well, right, but when not using that attribute, we shouldn't generate incorrect code. llvm shouldn't issue a POPFQ unless it knows that it's not blowing away an updated EFLAGS.

jfb added a comment.Jan 20 2016, 8:42 PM
In D15240#332004, @jfb wrote:

Agreed, you'll need to compile with -mattr=+sahf to avoid that issue.

Well, right, but when not using that attribute, we shouldn't generate incorrect code. llvm shouldn't issue a POPFQ unless it knows that it's not blowing away an updated EFLAGS.

Agreed. We're playing a game of whack-a-bug and a significant number of programs expect to run on machines with lahf/sahf so those uses won out on programs which get sad when EFLAGS are clobbered. That was the pre-D6629 status-quo, but the world is slightly better overall. It'll take another whack (and a big one at that) to fix the EFLAGS issue.