Open
Description
What version of Go are you using (go version
)?
$ go version go version devel go1.20-51834965b7 Sun Nov 13 02:26:29 2022 +0100 linux/amd64
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/home/hugo/.cache/go-build" GOENV="/home/hugo/.config/go/env" GOEXE="" GOEXPERIMENT="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GOMODCACHE="/home/hugo/go/pkg/mod" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/home/hugo/go" GOPRIVATE="" GOPROXY="direct" GOROOT="/home/hugo/k/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/home/hugo/k/go/pkg/tool/linux_amd64" GOVCS="" GOVERSION="devel go1.20-51834965b7 Sun Nov 13 02:26:29 2022 +0100" GCCGO="gccgo" GOAMD64="v3" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="/home/hugo/Documents/Scripts/go/src/cmd/go.mod" GOWORK="" CGO_CFLAGS="-O2 -g" CGO_CPPFLAGS="" CGO_CXXFLAGS="-O2 -g" CGO_FFLAGS="-O2 -g" CGO_LDFLAGS="-O2 -g" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build125027850=/tmp/go-build -gno-record-gcc-switches"
What did you do?
I was refactoring some SSA rules to canonicalize inversed comparision Ops similar to how LLVM do it.
(for example (NE cond yes no) => (EQ cond no yes)
)
This aims to simplify rules because we would have to handle only half as many rules for thoses that touch flags.
What did you expect to see?
I am expecting to see similar suffixes names between all instructions that use flag suffixes, similar to how the intel manual do Jcc
, SETcc
, CMOVcc
, ...
What did you see instead?
Blocks (Jcc
), CMOV
and SET
sometime use different names for the flags suffixes.
// Legend
Op Name -> Assembly Mnemonic
!MISSING! // this indicate that the arch have the instruction but we don't have an ssa Op for it
?MISSING? // this indicate that there is no corresponding ssa Op but there is probably a good reason behind it
// ZF == 0, good
SETEQ -> SETEQ
CMOVQEQ -> CMOVQEQ
EQ -> JEQ
// ZF == 1, good
SETNE -> SETNE
CMOVQNE -> CMOVQNE
NE -> JNE
// CF == 0 && ZF == 0
SETA -> SETHI // different
CMOVQHI -> CMOVQHI
UGT -> JHI // different
// CF == 1 || ZF == 1
SETBE -> SETLS // different
CMOVQLS -> CMOVQLS
ULE -> JLS // different
// ZF == 0 && SF == OF
SETG -> SETGT // different
CMOVQGT -> CMOVQGT
GT -> JGT
// ZF == 1 || SF != OF, good
SETLE -> SETLE
CMOVQLE -> CMOVQLE
LE -> JLE
// SF == OF, good
SETGE -> SETGE
CMOVQGE -> CMOVQGE
GE -> JGE
// SF != OF
SETL -> SETLT // different
CMOVQLT -> CMOVQLT
LT -> JLT
// CF == 0
SETAE -> SETCC // different
CMOVQCC -> CMOVQCC
UGE -> JCC // different
// CF == 1
SETB -> SETCS // different
CMOVQCS -> CMOVQCS
ULT -> JCS // different
// OF == 0
!MISSING!
!MISSING!
OC -> JOC // unused
// OF == 1
SETO -> SETOS // different
!MISSING!
OS -> JOS
// Need different opcodes for floating point conditions because
// any comparison involving a NaN is always FALSE and thus
// the patterns for inverting conditions cannot be used.
// A == B
SETEQF -> SETEQ
CMOVQEQF -> CMOVQNE // wrong ? Unused anyway
EQF -> JEQ
// A != B, good
SETNEF -> SETNE
CMOVQNEF -> CMOVQNE
NEF -> JNE
// is "ordered" ?
SETORD -> SETPC // unused
!MISSING!
ORD -> JPC // unused
// is NaN ?
SETNAN -> SETPS
!MISSING!
NAN -> JPS // unused
// a > b
SETGF -> SETHI // different
CMOVQGTF -> CMOVQHI
?MISSING? => UGT -> JHI
// a >= v
SETGEF -> SETCC
CMOVQGEF -> CMOVQCC
?MISSING? => UGE -> JCC
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Todo