diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -2722,6 +2722,9 @@ llvm_unreachable("Unknown constant value to lower!"); } + // The constant expression opcodes are limited to those that are necessary + // to represent relocations on supported targets. Expressions involving only + // constant addresses are constant folded instead. switch (CE->getOpcode()) { case Instruction::AddrSpaceCast: { const Constant *Op = CE->getOperand(0); @@ -2839,34 +2842,17 @@ return RelocExpr; } } + + const MCExpr *LHS = lowerConstant(CE->getOperand(0)); + const MCExpr *RHS = lowerConstant(CE->getOperand(1)); + return MCBinaryExpr::createSub(LHS, RHS, Ctx); + break; } - // else fallthrough - LLVM_FALLTHROUGH; - - // The MC library also has a right-shift operator, but it isn't consistently - // signed or unsigned between different targets. - case Instruction::Add: - case Instruction::Mul: - case Instruction::SDiv: - case Instruction::SRem: - case Instruction::Shl: - case Instruction::And: - case Instruction::Or: - case Instruction::Xor: { + + case Instruction::Add: { const MCExpr *LHS = lowerConstant(CE->getOperand(0)); const MCExpr *RHS = lowerConstant(CE->getOperand(1)); - switch (CE->getOpcode()) { - default: llvm_unreachable("Unknown binary operator constant cast expr"); - case Instruction::Add: return MCBinaryExpr::createAdd(LHS, RHS, Ctx); - case Instruction::Sub: return MCBinaryExpr::createSub(LHS, RHS, Ctx); - case Instruction::Mul: return MCBinaryExpr::createMul(LHS, RHS, Ctx); - case Instruction::SDiv: return MCBinaryExpr::createDiv(LHS, RHS, Ctx); - case Instruction::SRem: return MCBinaryExpr::createMod(LHS, RHS, Ctx); - case Instruction::Shl: return MCBinaryExpr::createShl(LHS, RHS, Ctx); - case Instruction::And: return MCBinaryExpr::createAnd(LHS, RHS, Ctx); - case Instruction::Or: return MCBinaryExpr::createOr (LHS, RHS, Ctx); - case Instruction::Xor: return MCBinaryExpr::createXor(LHS, RHS, Ctx); - } + return MCBinaryExpr::createAdd(LHS, RHS, Ctx); } } } diff --git a/llvm/test/CodeGen/X86/nonconst-static-div.ll b/llvm/test/CodeGen/X86/nonconst-static-div.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/nonconst-static-div.ll @@ -0,0 +1,12 @@ +; RUN: not --crash llc -mtriple=i686-linux-gnu < %s 2>&1 | FileCheck %s + +; Targets only support a limited set of relocations. Make sure that unusual +; constant expressions (and in particular potentially trapping ones involving +; division) are already rejected when lowering the Constant to the MC layer, +; rather than only when trying to emit a relocation. This makes sure that an +; error is reported when targeting assembly (without -filetype=obj). + +@g = external global i32 +@g2 = global i64 sdiv (i64 3, i64 ptrtoint (ptr @g to i64)) + +; CHECK: Unsupported expression in static initializer: sdiv diff --git a/llvm/test/CodeGen/X86/ptrtoint-constexpr.ll b/llvm/test/CodeGen/X86/ptrtoint-constexpr.ll --- a/llvm/test/CodeGen/X86/ptrtoint-constexpr.ll +++ b/llvm/test/CodeGen/X86/ptrtoint-constexpr.ll @@ -9,6 +9,6 @@ ; CHECK: .globl x ; CHECK: x: -; CHECK: .quad ((0+1)&4294967295)*3 +; CHECK: .quad 3 @x = global i64 mul (i64 3, i64 ptrtoint (ptr getelementptr (i2, ptr null, i64 1) to i64))