-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[SimplifyCFG] Make i1 legal to build lookup tables #87431
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
base: main
Are you sure you want to change the base?
Conversation
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write If you have received no comments on your PR for a week, you can request a review If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
Can you please add a test in llvm/test/Transforms/SimplifyCFG (something that doesn't fold without your change and folds with)? It's a bit hard to tell what exactly it is you are trying to fix here. |
87c924e
to
863cd17
Compare
@llvm/pr-subscribers-llvm-transforms Author: Arthur Carcano (krtab) ChangesThis is my attempt to fix the LLVM issue leading to rust-lang/rust#123305 and my first contribution to LLVM.
I guess I should add a test? Could you point to me where? Full diff: https://github.com/llvm/llvm-project/pull/87431.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 55bbffb18879fb..af6ace5675bf52 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -6448,6 +6448,8 @@ static bool isTypeLegalForLookupTable(Type *Ty, const TargetTransformInfo &TTI,
// on ABI alignment and padding in the table to allow the load to be widened.
// Or we could widen the constants and truncate the load.
unsigned BitWidth = IT->getBitWidth();
+ if (BitWidth == 1)
+ return true;
return BitWidth >= 8 && isPowerOf2_32(BitWidth) &&
DL.fitsInLegalInteger(IT->getBitWidth());
}
diff --git a/llvm/test/Transforms/SimplifyCFG/fold-i1.ll b/llvm/test/Transforms/SimplifyCFG/fold-i1.ll
new file mode 100644
index 00000000000000..444f51fb2438bc
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/fold-i1.ll
@@ -0,0 +1,64 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt < %s -S -passes='simplifycfg<switch-to-lookup>' | FileCheck %s
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+
+define { i1, i8 } @f(i8 noundef %character) unnamed_addr {
+; CHECK-LABEL: define { i1, i8 } @f(
+; CHECK-SAME: i8 noundef [[CHARACTER:%.*]]) unnamed_addr {
+; CHECK-NEXT: start:
+; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i8 [[CHARACTER]], 48
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i8 [[SWITCH_TABLEIDX]], 9
+; CHECK-NEXT: [[_0_SROA_11_0:%.*]] = select i1 [[TMP2]], i8 [[SWITCH_TABLEIDX]], i8 undef
+; CHECK-NEXT: [[_0_SROA_0_0:%.*]] = select i1 [[TMP2]], i1 true, i1 false
+; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { i1, i8 } poison, i1 [[_0_SROA_0_0]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i1, i8 } [[TMP0]], i8 [[_0_SROA_11_0]], 1
+; CHECK-NEXT: ret { i1, i8 } [[TMP1]]
+;
+start:
+ switch i8 %character, label %bb11 [
+ i8 48, label %bb2
+ i8 49, label %bb3
+ i8 50, label %bb4
+ i8 51, label %bb5
+ i8 52, label %bb6
+ i8 53, label %bb7
+ i8 54, label %bb8
+ i8 55, label %bb9
+ i8 56, label %bb10
+ ]
+
+bb2:
+ br label %bb11
+
+bb3:
+ br label %bb11
+
+bb4:
+ br label %bb11
+
+bb5:
+ br label %bb11
+
+bb6:
+ br label %bb11
+
+bb7:
+ br label %bb11
+
+bb8:
+ br label %bb11
+
+bb9:
+ br label %bb11
+
+bb10:
+ br label %bb11
+
+bb11:
+ %_0.sroa.11.0 = phi i8 [ 8, %bb10 ], [ 7, %bb9 ], [ 6, %bb8 ], [ 5, %bb7 ], [ 4, %bb6 ], [ 3, %bb5 ], [ 2, %bb4 ], [ 1, %bb3 ], [ 0, %bb2 ], [ undef, %start ]
+ %_0.sroa.0.0 = phi i1 [ true, %bb10 ], [ true, %bb9 ], [ true, %bb8 ], [ true, %bb7 ], [ true, %bb6 ], [ true, %bb5 ], [ true, %bb4 ], [ true, %bb3 ], [ true, %bb2 ], [ false, %start ]
+ %0 = insertvalue { i1, i8 } poison, i1 %_0.sroa.0.0, 0
+ %1 = insertvalue { i1, i8 } %0, i8 %_0.sroa.11.0, 1
+ ret { i1, i8 } %1
+}
|
I've added a test @nikic , let me know it this should be improved. |
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i8 [[CHARACTER]], 48 | ||
; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i8 [[SWITCH_TABLEIDX]], 9 | ||
; CHECK-NEXT: [[_0_SROA_11_0:%.*]] = select i1 [[TMP2]], i8 [[SWITCH_TABLEIDX]], i8 undef | ||
; CHECK-NEXT: [[_0_SROA_0_0:%.*]] = select i1 [[TMP2]], i1 true, i1 false |
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.
It would be good to also test the case where we actually build a lookup table for the booleans. Need some pattern for that which doesn't reduce down to a simple select.
If I'm reading the code right, then what we'd end up doing is generate an array of i1 constants and then generate i1 loads -- the former is okay-ish, but the latter is a big no-no. We'd instead want to generate a table of i8s, generate i8 loads and truncate them to i1.
An alternative would be to not allow table generation, but instead relax the "AllTablesFitInRegister" condition so that we always have either a legal integer width or the lookup mask fitting in a register, without requiring that all of them fit in a register.
This is my attempt to fix the LLVM issue leading to rust-lang/rust#123305 and my first contribution to LLVM.
i1
types are not considered to simplify switches because they are!isTypeLegalForLookupTable
. This hardcode an exception but other ways may make more sense.I guess I should add a test? Could you point to me where?