-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SOL] Remove neg
and change the semantics of sub
#73
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,6 +54,8 @@ def SBFIsBigEndian : Predicate<"!CurDAG->getDataLayout().isLittleEndian()">; | |
def SBFHasALU32 : Predicate<"Subtarget->getHasAlu32()">; | ||
def SBFNoALU32 : Predicate<"!Subtarget->getHasAlu32()">; | ||
def SBFSubtargetSolana : Predicate<"Subtarget->isSolana()">; | ||
def SBFv2 : Predicate<"Subtarget->isSBFv2()">; | ||
def NoSBFv2 : Predicate<"!Subtarget->isSBFv2()">; | ||
|
||
def brtarget : Operand<OtherVT> { | ||
let PrintMethod = "printBrTargetOperand"; | ||
|
@@ -263,7 +265,7 @@ class ALU_RR<SBFOpClass Class, SBFArithOp Opc, | |
let SBFClass = Class; | ||
} | ||
|
||
multiclass ALU<SBFArithOp Opc, string Mnemonic, SDNode OpNode> { | ||
multiclass ALU<SBFArithOp Opc, string Mnemonic, SDNode OpNode, bit UseImmPat = 1> { | ||
def _rr : ALU_RR<SBF_ALU64, Opc, | ||
(outs GPR:$dst), | ||
(ins GPR:$src2, GPR:$src), | ||
|
@@ -273,7 +275,9 @@ multiclass ALU<SBFArithOp Opc, string Mnemonic, SDNode OpNode> { | |
(outs GPR:$dst), | ||
(ins GPR:$src2, i64imm:$imm), | ||
Mnemonic # "64 $dst, $imm", | ||
[(set GPR:$dst, (OpNode GPR:$src2, i64immSExt32:$imm))]>; | ||
!if(UseImmPat, | ||
[(set GPR:$dst, | ||
(OpNode GPR:$src2, i64immSExt32:$imm))], [])>; | ||
def _rr_32 : ALU_RR<SBF_ALU, Opc, | ||
(outs GPR32:$dst), | ||
(ins GPR32:$src2, GPR32:$src), | ||
|
@@ -283,13 +287,15 @@ multiclass ALU<SBFArithOp Opc, string Mnemonic, SDNode OpNode> { | |
(outs GPR32:$dst), | ||
(ins GPR32:$src2, i32imm:$imm), | ||
Mnemonic # "32 $dst, $imm", | ||
[(set GPR32:$dst, (OpNode GPR32:$src2, i32immSExt32:$imm))]>; | ||
!if(UseImmPat, | ||
[(set GPR32:$dst, | ||
(OpNode GPR32:$src2, i32immSExt32:$imm))], [])>; | ||
} | ||
|
||
let Constraints = "$dst = $src2" in { | ||
let isAsCheapAsAMove = 1 in { | ||
defm ADD : ALU<SBF_ADD, "add", add>; | ||
defm SUB : ALU<SBF_SUB, "sub", sub>; | ||
defm SUB : ALU<SBF_SUB, "sub", sub, 0>; | ||
defm OR : ALU<SBF_OR, "or", or>; | ||
defm AND : ALU<SBF_AND, "and", and>; | ||
defm SLL : ALU<SBF_LSH, "lsh", shl>; | ||
|
@@ -306,6 +312,19 @@ let Constraints = "$dst = $src2" in { | |
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The entire part of the patch above involving the
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One related general question I have is-- should we conditionally be generating the swapped special case There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The new syntax can be behind the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I couldn't find a way to encapsulate the new There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Everything should be behind a feature flag now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for incorporating my offline suggestions, this is ready to land (other than some trivial coding standard nits, which I'll note shortly). |
||
|
||
// Special case for SBFv2 | ||
// In SBFv1, `sub reg, imm` is interpreted as reg = reg - imm, | ||
// but in SBFv2 it means reg = imm - reg | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. LLVM Coding standard nit: (Proper prose, capitalization, punctuation) Please add period/full-stops (as in the original comments that I had written-- but your wording is fine).
|
||
def : Pat<(sub GPR:$src, i64immSExt32:$imm), | ||
(SUB_ri GPR:$src, i64immSExt32:$imm)>, Requires<[NoSBFv2]>; | ||
def : Pat<(sub GPR32:$src, i32immSExt32:$imm), | ||
(SUB_ri_32 GPR32:$src, i32immSExt32:$imm)>, Requires<[NoSBFv2]>; | ||
|
||
def : Pat<(sub i64immSExt32:$imm, GPR:$src), | ||
(SUB_ri GPR:$src, i64immSExt32:$imm)>, Requires<[SBFv2]>; | ||
def : Pat<(sub i32immSExt32:$imm, GPR32:$src), | ||
(SUB_ri_32 GPR32:$src, i32immSExt32:$imm)>, Requires<[SBFv2]>; | ||
|
||
class NEG_RR<SBFOpClass Class, SBFArithOp Opc, | ||
dag outs, dag ins, string asmstr, list<dag> pattern> | ||
: TYPE_ALU_JMP<Opc.Value, 0, outs, ins, asmstr, pattern> { | ||
|
@@ -318,12 +337,21 @@ class NEG_RR<SBFOpClass Class, SBFArithOp Opc, | |
let Constraints = "$dst = $src", isAsCheapAsAMove = 1 in { | ||
def NEG_64: NEG_RR<SBF_ALU64, SBF_NEG, (outs GPR:$dst), (ins GPR:$src), | ||
"neg64 $dst", | ||
[(set GPR:$dst, (ineg i64:$src))]>; | ||
[]>; | ||
def NEG_32: NEG_RR<SBF_ALU, SBF_NEG, (outs GPR32:$dst), (ins GPR32:$src), | ||
"neg32 $dst", | ||
[(set GPR32:$dst, (ineg i32:$src))]>; | ||
[]>; | ||
} | ||
|
||
// Instruction `neg` exists on SBFv1, but not on SBFv2 | ||
// In SBFv2, the negate operation is done with a subtraction | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto: Periods/full-stops. |
||
def : Pat<(ineg i64:$src), (NEG_64 GPR:$src)>, Requires<[NoSBFv2]>; | ||
def : Pat<(ineg i32:$src), (NEG_32 GPR32:$src)>, Requires<[NoSBFv2]>; | ||
|
||
def : Pat<(ineg i64:$src), (SUB_ri GPR:$src, 0)>, Requires<[SBFv2]>; | ||
def : Pat<(ineg i32:$src), (SUB_ri_32 GPR32:$src, 0)>, Requires<[SBFv2]>; | ||
|
||
|
||
class LD_IMM64<bits<4> Pseudo, string Mnemonic> | ||
: TYPE_LD_ST<SBF_IMM.Value, SBF_DW.Value, | ||
(outs GPR:$dst), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
; RUN: llc < %s -march=sbf -mattr=+alu32 | FileCheck --check-prefix=CHECK-v1 %s | ||
; RUN: llc < %s -march=sbf -mattr=+alu32 -mcpu=sbfv2 | FileCheck --check-prefix=CHECK-v2 %s | ||
|
||
|
||
; Function Attrs: norecurse nounwind readnone | ||
define dso_local i64 @sub_imm_minus_reg_64(i64 %a) #0 { | ||
entry: | ||
; CHECK-LABEL: sub_imm_minus_reg_64: | ||
%sub = sub nsw i64 50, %a | ||
|
||
; CHECK-v1: mov64 r{{[0-9]+}}, 50 | ||
; CHECK-v1: sub64 r{{[0-9]+}}, r{{[0-9]+}} | ||
|
||
; CHECK-v2: sub64 r{{[0-9]+}}, 50 | ||
ret i64 %sub | ||
} | ||
|
||
; Function Attrs: norecurse nounwind readnone | ||
define dso_local i64 @sub_reg_minus_imm_64(i64 %a) #0 { | ||
entry: | ||
; CHECK-LABEL: sub_reg_minus_imm_64: | ||
%t = sub nsw i64 %a, 50 | ||
; CHECK-v1: add64 r{{[0-9]+}}, -50 | ||
|
||
; CHECK-v2: add64 r{{[0-9]+}}, -50 | ||
ret i64 %t | ||
} | ||
|
||
|
||
; Function Attrs: norecurse nounwind readnone | ||
define dso_local i32 @sub_imm_minus_reg_32(i32 %a) #0 { | ||
entry: | ||
; CHECK-LABEL: sub_imm_minus_reg_32: | ||
%sub = sub nsw i32 50, %a | ||
|
||
; CHECK-v1: mov32 w{{[0-9]+}}, 50 | ||
; CHECK-v1: sub32 w{{[0-9]+}}, w{{[0-9]+}} | ||
|
||
; CHECK-v2: sub32 w{{[0-9]+}}, 50 | ||
|
||
ret i32 %sub | ||
} | ||
|
||
; Function Attrs: norecurse nounwind readnone | ||
define dso_local i32 @sub_reg_minus_imm_32(i32 %a) #0 { | ||
entry: | ||
; CHECK-LABEL: sub_reg_minus_imm_32: | ||
%t = sub nsw i32 %a, 50 | ||
|
||
; CHECK-v1: add32 w{{[0-9]+}}, -50 | ||
|
||
; CHECK-v2: add32 w{{[0-9]+}}, -50 | ||
ret i32 %t | ||
} | ||
|
||
|
||
; Function Attrs: norecurse nounwind readnone | ||
define dso_local i64 @neg_64(i64 %a) #0 { | ||
entry: | ||
; CHECK-LABEL: neg_64: | ||
%sub = sub nsw i64 0, %a | ||
|
||
; CHECK-v1: neg64 r{{[0-9]+}} | ||
; CHECK-v2: sub64 r{{[0-9]+}}, 0 | ||
|
||
ret i64 %sub | ||
} | ||
|
||
; Function Attrs: norecurse nounwind readnone | ||
define dso_local i32 @neg_32(i32 %a) #0 { | ||
entry: | ||
; CHECK-LABEL: neg_32: | ||
%sub = sub nsw i32 0, %a | ||
|
||
; CHECK-v1: neg32 w{{[0-9]+}} | ||
; CHECK-v2: sub32 w{{[0-9]+}}, 0 | ||
|
||
ret i32 %sub | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LLVM Coding standard nit: (80-column rules) Please move the new parameter to the next line, aligned with the
<
'.