-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[SLP] Make getSameOpcode support interchangeable instructions. #132887
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
Conversation
@llvm/pr-subscribers-llvm-transforms Author: Han-Kuan Chen (HanKuanChen) ChangesIf the Converter has AltOp, that means I should be converted to AltOp Full diff: https://github.com/llvm/llvm-project/pull/132887.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 72e18be9fe71e..6d96aedc5ff9f 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -1094,12 +1094,9 @@ class BinOpSameOpcodeHelper {
unsigned getAltOpcode() const {
return hasAltOp() ? AltOp.getOpcode() : getMainOpcode();
}
- SmallVector<Value *> getMainOperand(Instruction *I) const {
+ SmallVector<Value *> getOperand(Instruction *I) const {
return MainOp.getOperand(I);
}
- SmallVector<Value *> getAltOperand(Instruction *I) const {
- return AltOp.getOperand(I);
- }
};
bool isConvertible(Instruction *I, Instruction *MainOp, Instruction *AltOp) {
@@ -1126,8 +1123,8 @@ convertTo(Instruction *I, Instruction *MainOp, Instruction *AltOp) {
assert(I->isBinaryOp() && "Cannot convert the instruction.");
BinOpSameOpcodeHelper Converter(I);
if (Converter.add(I) && Converter.add(MainOp) && !Converter.hasAltOp())
- return std::make_pair(MainOp, Converter.getMainOperand(MainOp));
- return std::make_pair(AltOp, Converter.getAltOperand(AltOp));
+ return std::make_pair(MainOp, Converter.getOperand(MainOp));
+ return std::make_pair(AltOp, Converter.getOperand(AltOp));
}
/// Main data required for vectorization of instructions.
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/BinOpSameOpcodeHelper.ll b/llvm/test/Transforms/SLPVectorizer/X86/BinOpSameOpcodeHelper.ll
new file mode 100644
index 0000000000000..6f27555aeb3f1
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/BinOpSameOpcodeHelper.ll
@@ -0,0 +1,36 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -mtriple=x86_64-unknown-linux-gnu -passes=slp-vectorizer -S %s | FileCheck %s
+
+define void @test() {
+; CHECK-LABEL: @test(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = lshr i64 0, 0
+; CHECK-NEXT: [[TMP1:%.*]] = sub i64 0, 1
+; CHECK-NEXT: [[TMP2:%.*]] = lshr i64 [[TMP1]], 0
+; CHECK-NEXT: [[UMIN120:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP0]], i64 [[TMP2]])
+; CHECK-NEXT: [[TMP3:%.*]] = sub i64 0, 0
+; CHECK-NEXT: [[TMP4:%.*]] = lshr i64 [[TMP3]], 0
+; CHECK-NEXT: [[UMIN122:%.*]] = call i64 @llvm.umin.i64(i64 [[UMIN120]], i64 [[TMP4]])
+; CHECK-NEXT: [[TMP5:%.*]] = add i64 0, 1
+; CHECK-NEXT: [[TMP6:%.*]] = lshr i64 [[TMP5]], 0
+; CHECK-NEXT: [[UMIN123:%.*]] = call i64 @llvm.umin.i64(i64 [[UMIN122]], i64 [[TMP6]])
+; CHECK-NEXT: [[UMIN124:%.*]] = call i64 @llvm.umin.i64(i64 [[UMIN123]], i64 0)
+; CHECK-NEXT: ret void
+;
+entry:
+ %0 = mul i64 0, 0
+ %1 = lshr i64 %0, 0
+ %2 = sub i64 0, 1
+ %3 = lshr i64 %2, 0
+ %umin120 = call i64 @llvm.umin.i64(i64 %1, i64 %3)
+ %4 = sub i64 0, 0
+ %5 = lshr i64 %4, 0
+ %umin122 = call i64 @llvm.umin.i64(i64 %umin120, i64 %5)
+ %6 = add i64 0, 1
+ %7 = lshr i64 %6, 0
+ %umin123 = call i64 @llvm.umin.i64(i64 %umin122, i64 %7)
+ %umin124 = call i64 @llvm.umin.i64(i64 %umin123, i64 0)
+ ret void
+}
+
+declare i64 @llvm.umin.i64(i64, i64)
|
@llvm/pr-subscribers-vectorizers Author: Han-Kuan Chen (HanKuanChen) ChangesIf the Converter has AltOp, that means I should be converted to AltOp Full diff: https://github.com/llvm/llvm-project/pull/132887.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 72e18be9fe71e..6d96aedc5ff9f 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -1094,12 +1094,9 @@ class BinOpSameOpcodeHelper {
unsigned getAltOpcode() const {
return hasAltOp() ? AltOp.getOpcode() : getMainOpcode();
}
- SmallVector<Value *> getMainOperand(Instruction *I) const {
+ SmallVector<Value *> getOperand(Instruction *I) const {
return MainOp.getOperand(I);
}
- SmallVector<Value *> getAltOperand(Instruction *I) const {
- return AltOp.getOperand(I);
- }
};
bool isConvertible(Instruction *I, Instruction *MainOp, Instruction *AltOp) {
@@ -1126,8 +1123,8 @@ convertTo(Instruction *I, Instruction *MainOp, Instruction *AltOp) {
assert(I->isBinaryOp() && "Cannot convert the instruction.");
BinOpSameOpcodeHelper Converter(I);
if (Converter.add(I) && Converter.add(MainOp) && !Converter.hasAltOp())
- return std::make_pair(MainOp, Converter.getMainOperand(MainOp));
- return std::make_pair(AltOp, Converter.getAltOperand(AltOp));
+ return std::make_pair(MainOp, Converter.getOperand(MainOp));
+ return std::make_pair(AltOp, Converter.getOperand(AltOp));
}
/// Main data required for vectorization of instructions.
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/BinOpSameOpcodeHelper.ll b/llvm/test/Transforms/SLPVectorizer/X86/BinOpSameOpcodeHelper.ll
new file mode 100644
index 0000000000000..6f27555aeb3f1
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/BinOpSameOpcodeHelper.ll
@@ -0,0 +1,36 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -mtriple=x86_64-unknown-linux-gnu -passes=slp-vectorizer -S %s | FileCheck %s
+
+define void @test() {
+; CHECK-LABEL: @test(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = lshr i64 0, 0
+; CHECK-NEXT: [[TMP1:%.*]] = sub i64 0, 1
+; CHECK-NEXT: [[TMP2:%.*]] = lshr i64 [[TMP1]], 0
+; CHECK-NEXT: [[UMIN120:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP0]], i64 [[TMP2]])
+; CHECK-NEXT: [[TMP3:%.*]] = sub i64 0, 0
+; CHECK-NEXT: [[TMP4:%.*]] = lshr i64 [[TMP3]], 0
+; CHECK-NEXT: [[UMIN122:%.*]] = call i64 @llvm.umin.i64(i64 [[UMIN120]], i64 [[TMP4]])
+; CHECK-NEXT: [[TMP5:%.*]] = add i64 0, 1
+; CHECK-NEXT: [[TMP6:%.*]] = lshr i64 [[TMP5]], 0
+; CHECK-NEXT: [[UMIN123:%.*]] = call i64 @llvm.umin.i64(i64 [[UMIN122]], i64 [[TMP6]])
+; CHECK-NEXT: [[UMIN124:%.*]] = call i64 @llvm.umin.i64(i64 [[UMIN123]], i64 0)
+; CHECK-NEXT: ret void
+;
+entry:
+ %0 = mul i64 0, 0
+ %1 = lshr i64 %0, 0
+ %2 = sub i64 0, 1
+ %3 = lshr i64 %2, 0
+ %umin120 = call i64 @llvm.umin.i64(i64 %1, i64 %3)
+ %4 = sub i64 0, 0
+ %5 = lshr i64 %4, 0
+ %umin122 = call i64 @llvm.umin.i64(i64 %umin120, i64 %5)
+ %6 = add i64 0, 1
+ %7 = lshr i64 %6, 0
+ %umin123 = call i64 @llvm.umin.i64(i64 %umin122, i64 %7)
+ %umin124 = call i64 @llvm.umin.i64(i64 %umin123, i64 0)
+ ret void
+}
+
+declare i64 @llvm.umin.i64(i64, i64)
|
…127450) We use the term "interchangeable instructions" to refer to different operators that have the same meaning (e.g., `add x, 0` is equivalent to `mul x, 1`). Non-constant values are not supported, as they may incur high costs with little benefit. --------- Co-authored-by: Alexey Bataev <[email protected]>
If the Converter has AltOp, that means I should be converted to AltOp instead of MainOp (which is AltOp in BinOpSameOpcodeHelper).
120fb17
to
58f09d6
Compare
You can test this locally with the following command:git diff -U0 --pickaxe-regex -S '([^a-zA-Z0-9#_-]undef[^a-zA-Z0-9_-]|UndefValue::get)' 07c82b1622de1c5c4329ffb769bef7fef1b07429 58f09d66f8b22bf52994c8f3e125f99506c96fe8 llvm/test/Transforms/SLPVectorizer/X86/BinOpSameOpcodeHelper.ll llvm/test/Transforms/SLPVectorizer/isOpcodeOrAlt.ll llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp llvm/test/Transforms/SLPVectorizer/AArch64/vec3-base.ll llvm/test/Transforms/SLPVectorizer/RISCV/reversed-strided-node-with-external-ptr.ll llvm/test/Transforms/SLPVectorizer/RISCV/vec3-base.ll llvm/test/Transforms/SLPVectorizer/X86/barriercall.ll llvm/test/Transforms/SLPVectorizer/X86/bottom-to-top-reorder.ll llvm/test/Transforms/SLPVectorizer/X86/buildvector-postpone-for-dependency.ll llvm/test/Transforms/SLPVectorizer/X86/bv-shuffle-mask.ll llvm/test/Transforms/SLPVectorizer/X86/extract-scalar-from-undef.ll llvm/test/Transforms/SLPVectorizer/X86/extractcost.ll llvm/test/Transforms/SLPVectorizer/X86/gathered-delayed-nodes-with-reused-user.ll llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-drop-wrapping-flags.ll llvm/test/Transforms/SLPVectorizer/X86/multi-extracts-bv-combined.ll llvm/test/Transforms/SLPVectorizer/X86/non-scheduled-inst-reused-as-last-inst.ll llvm/test/Transforms/SLPVectorizer/X86/propagate_ir_flags.ll llvm/test/Transforms/SLPVectorizer/X86/reduced-val-vectorized-in-transform.ll llvm/test/Transforms/SLPVectorizer/X86/reorder_diamond_match.ll llvm/test/Transforms/SLPVectorizer/X86/shuffle-mask-emission.ll llvm/test/Transforms/SLPVectorizer/X86/vec3-base.ll llvm/test/Transforms/SLPVectorizer/X86/vect_copyable_in_binops.ll llvm/test/Transforms/SLPVectorizer/alternate-opcode-sindle-bv.ll llvm/test/Transforms/SLPVectorizer/resized-alt-shuffle-after-minbw.ll llvm/test/Transforms/SLPVectorizer/shuffle-mask-resized.ll The following files introduce new uses of undef:
Undef is now deprecated and should only be used in the rare cases where no replacement is possible. For example, a load of uninitialized memory yields In tests, avoid using For example, this is considered a bad practice: define void @fn() {
...
br i1 undef, ...
} Please use the following instead: define void @fn(i1 %cond) {
...
br i1 %cond, ...
} Please refer to the Undefined Behavior Manual for more information. |
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/59/builds/14891 Here is the relevant piece of the build log for the reference
|
#132887)" This reverts commit 6e66cfe. This change causes crashes on compiling some inputs, see #127450 (comment) and #127450 (comment) for details.
We see a Clang crash after 8122bb9 and 6e66cfe (unfortunately, I don't know yet more precisely, which of the two is the culprit, but they were committed one after another). See 8122bb9#commitcomment-154471110 |
It's addressed by the revert a2e5932. |
…132887) We use the term "interchangeable instructions" to refer to different operators that have the same meaning (e.g., `add x, 0` is equivalent to `mul x, 1`). Non-constant values are not supported, as they may incur high costs with little benefit. --------- Co-authored-by: Alexey Bataev <[email protected]>
If the Converter has AltOp, that means I should be converted to AltOp
instead of MainOp (which is AltOp in BinOpSameOpcodeHelper).