[llvm] a800817 - [SimplifyCFG] Avoid shifting by a too large exponent.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 29 07:19:26 PDT 2022


Author: Florian Hahn
Date: 2022-04-29T15:19:06+01:00
New Revision: a80081763cb3792bf69ee95ee73c8754f1bfe074

URL: https://github.com/llvm/llvm-project/commit/a80081763cb3792bf69ee95ee73c8754f1bfe074
DIFF: https://github.com/llvm/llvm-project/commit/a80081763cb3792bf69ee95ee73c8754f1bfe074.diff

LOG: [SimplifyCFG] Avoid shifting by a too large exponent.

TI->getBitWidth can be > 64 and in those cases the shift will be UB due
to the exponent being too large.

To fix this, cap the shift at 63. I think this should work out fine,
because TableSize is itself a 64 bit type and the maximum table size
must fit in the type. Also, if we would underestimate the size here, at
most we get an extra ZExt.

Reviewed By: spatel

Differential Revision: https://reviews.llvm.org/D124608

Added: 
    llvm/test/Transforms/SimplifyCFG/X86/switch-to-lookup-large-types.ll

Modified: 
    llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index e86d253b9b9f0..f419ba58bbcf1 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -6055,7 +6055,7 @@ Value *SwitchLookupTable::BuildLookup(Value *Index, IRBuilder<> &Builder) {
     IntegerType *IT = cast<IntegerType>(Index->getType());
     uint64_t TableSize =
         Array->getInitializer()->getType()->getArrayNumElements();
-    if (TableSize > (1ULL << (IT->getBitWidth() - 1)))
+    if (TableSize > (1ULL << std::min(IT->getBitWidth() - 1, 63u)))
       Index = Builder.CreateZExt(
           Index, IntegerType::get(IT->getContext(), IT->getBitWidth() + 1),
           "switch.tableidx.zext");

diff  --git a/llvm/test/Transforms/SimplifyCFG/X86/switch-to-lookup-large-types.ll b/llvm/test/Transforms/SimplifyCFG/X86/switch-to-lookup-large-types.ll
new file mode 100644
index 0000000000000..31c020f8523d0
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/X86/switch-to-lookup-large-types.ll
@@ -0,0 +1,75 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --scrub-attributes --check-globals
+; RUN: opt -passes=simplifycfg --switch-to-lookup -S %s | FileCheck %s
+target triple = "x86_64-unknown-linux-gnu"
+
+;.
+; CHECK: @[[SWITCH_TABLE_SWITCH_TO_LOOKUP_I64:[a-zA-Z0-9_$"\\.-]+]] = private unnamed_addr constant [3 x i8] c"\03\01\02", align 1
+; CHECK: @[[SWITCH_TABLE_SWITCH_TO_LOOKUP_I128:[a-zA-Z0-9_$"\\.-]+]] = private unnamed_addr constant [3 x i8] c"\03\01\02", align 1
+;.
+define i8 @switch_to_lookup_i64(i128 %x){
+; CHECK-LABEL: @switch_to_lookup_i64(
+; CHECK-NEXT:  start:
+; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i128 [[X:%.*]], 3
+; CHECK-NEXT:    br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[COMMON_RET:%.*]]
+; CHECK:       common.ret:
+; CHECK-NEXT:    [[COMMON_RET_OP:%.*]] = phi i8 [ [[SWITCH_LOAD:%.*]], [[SWITCH_LOOKUP]] ], [ 10, [[START:%.*]] ]
+; CHECK-NEXT:    ret i8 [[COMMON_RET_OP]]
+; CHECK:       switch.lookup:
+; CHECK-NEXT:    [[SWITCH_GEP:%.*]] = getelementptr inbounds [3 x i8], [3 x i8]* @switch.table.switch_to_lookup_i64, i32 0, i128 [[X]]
+; CHECK-NEXT:    [[SWITCH_LOAD]] = load i8, i8* [[SWITCH_GEP]], align 1
+; CHECK-NEXT:    br label [[COMMON_RET]]
+;
+start:
+  switch i128 %x, label %default [
+  i128 0, label %end
+  i128 1, label %bb1
+  i128 2, label %bb2
+  ]
+
+bb1:
+  br label %end
+
+bb2:
+  br label %end
+
+default:
+  ret i8 10
+
+end:
+  %p = phi i8 [ 1, %bb1 ], [ 2, %bb2 ], [ 3, %start ]
+  ret i8 %p
+}
+
+define i8 @switch_to_lookup_i128(i128 %x){
+; CHECK-LABEL: @switch_to_lookup_i128(
+; CHECK-NEXT:  start:
+; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i128 [[X:%.*]], 3
+; CHECK-NEXT:    br i1 [[TMP0]], label [[SWITCH_LOOKUP:%.*]], label [[COMMON_RET:%.*]]
+; CHECK:       common.ret:
+; CHECK-NEXT:    [[COMMON_RET_OP:%.*]] = phi i8 [ [[SWITCH_LOAD:%.*]], [[SWITCH_LOOKUP]] ], [ 10, [[START:%.*]] ]
+; CHECK-NEXT:    ret i8 [[COMMON_RET_OP]]
+; CHECK:       switch.lookup:
+; CHECK-NEXT:    [[SWITCH_GEP:%.*]] = getelementptr inbounds [3 x i8], [3 x i8]* @switch.table.switch_to_lookup_i128, i32 0, i128 [[X]]
+; CHECK-NEXT:    [[SWITCH_LOAD]] = load i8, i8* [[SWITCH_GEP]], align 1
+; CHECK-NEXT:    br label [[COMMON_RET]]
+;
+start:
+  switch i128 %x, label %default [
+  i128 0, label %end
+  i128 1, label %bb1
+  i128 2, label %bb2
+  ]
+
+bb1:
+  br label %end
+
+bb2:
+  br label %end
+
+default:
+  ret i8 10
+
+end:
+  %p = phi i8 [ 1, %bb1 ], [ 2, %bb2 ], [ 3, %start ]
+  ret i8 %p
+}


        


More information about the llvm-commits mailing list