Index: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp =================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp @@ -1643,10 +1643,12 @@ // instead of a select to synthesize the desired value. bool IsOneZero = false; bool EmitOneOrZero = true; - if (ConstantInt *CI = dyn_cast(OtherVal)){ + auto *CI = dyn_cast(OtherVal); + if (CI && CI->getValue().getActiveBits() <= 64) { IsOneZero = InitVal->isNullValue() && CI->isOne(); - if (ConstantInt *CIInit = dyn_cast(GV->getInitializer())){ + auto *CIInit = dyn_cast(GV->getInitializer()); + if (CIInit && CIInit->getValue().getActiveBits() <= 64) { uint64_t ValInit = CIInit->getZExtValue(); uint64_t ValOther = CI->getZExtValue(); uint64_t ValMinus = ValOther - ValInit; Index: llvm/trunk/test/Transforms/GlobalOpt/large-int-crash.ll =================================================================== --- llvm/trunk/test/Transforms/GlobalOpt/large-int-crash.ll +++ llvm/trunk/test/Transforms/GlobalOpt/large-int-crash.ll @@ -0,0 +1,23 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -globalopt -S | FileCheck %s + +@X = internal global i128 0 + +define void @foo() { +; CHECK-LABEL: @foo( +; CHECK-NEXT: [[T0_B:%.*]] = load i1, i1* @X +; CHECK-NEXT: [[T0:%.*]] = select i1 [[T0_B]], i128 18446744073709551616, i128 0 +; CHECK-NEXT: ret void +; + %t0 = load i128, i128* @X, align 8 + ret void +} + +define void @store() { +; CHECK-LABEL: @store( +; CHECK-NEXT: store i1 true, i1* @X +; CHECK-NEXT: ret void +; + store i128 18446744073709551616, i128* @X, align 8 + ret void +}