[llvm] 459bce1 - [ConstantFolding] Fold `bitinsert` and `bitextract` (#229115)

via llvm-commits llvm-commits at lists.llvm.org
Sat Oct 10 11:18:23 PDT 2026


Author: Pedro Lobo
Date: 2026-10-10T19:18:16+01:00
New Revision: 459bce1a5f1067a278011f71e64492cda077c0f1

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

LOG: [ConstantFolding] Fold `bitinsert` and `bitextract` (#229115)

Constant fold `bitinsert` and `bitextract`.

- Bits of a `ConstantByte` are extracted or inserted, then reinterpreted
as if by `bitcast`.
- A `bitinsert` that overwrites every bit of the base becomes a
`bitcast` of the value.
- An out-of-range, `poison` source or `poison`/`undef` offset returns
`poison`.

```llvm
%a = bitextract i8, b32 512, i32 8      ; i8 2
%b = bitinsert b32 0, i8 1, i32 8       ; b32 256
%c = bitinsert b16 0, half 1.0, i32 0   ; b16 15360, the bits of half 1.0
%d = bitextract i8, b32 0, i32 25       ; i8 poison
```

Added: 
    llvm/test/Transforms/InstSimplify/ConstProp/bitinsert-bitextract.ll

Modified: 
    llvm/include/llvm/Analysis/ConstantFolding.h
    llvm/include/llvm/Analysis/TargetFolder.h
    llvm/include/llvm/IR/ConstantFolder.h
    llvm/lib/Analysis/ConstantFolding.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/ConstantFolding.h b/llvm/include/llvm/Analysis/ConstantFolding.h
index 57c18108cb22b..e5c0883e31190 100644
--- a/llvm/include/llvm/Analysis/ConstantFolding.h
+++ b/llvm/include/llvm/Analysis/ConstantFolding.h
@@ -129,6 +129,20 @@ LLVM_ABI Constant *ConstantFoldCastOperand(unsigned Opcode, Constant *C,
 LLVM_ABI Constant *ConstantFoldIntegerCast(Constant *C, Type *DestTy,
                                            bool IsSigned, const DataLayout &DL);
 
+/// Attempt to constant fold a bitinsert instruction with the specified
+/// operands. The constant result is returned if successful. Otherwise, null is
+/// returned.
+LLVM_ABI Constant *ConstantFoldBitInsertOperands(Constant *Base, Constant *Val,
+                                                 Constant *Offset,
+                                                 const DataLayout &DL);
+
+/// Attempt to constant fold a bitextract instruction with the specified result
+/// type and operands. The constant result is returned if successful.
+/// Otherwise, null is returned.
+LLVM_ABI Constant *ConstantFoldBitExtractOperands(Type *Ty, Constant *Src,
+                                                  Constant *Offset,
+                                                  const DataLayout &DL);
+
 /// Extract value of C at the given Offset reinterpreted as Ty. If bits past
 /// the end of C are accessed, they are assumed to be poison.
 LLVM_ABI Constant *ConstantFoldLoadFromConst(Constant *C, Type *Ty,

diff  --git a/llvm/include/llvm/Analysis/TargetFolder.h b/llvm/include/llvm/Analysis/TargetFolder.h
index 65bbb8b74d4ad..3b23de62ffe47 100644
--- a/llvm/include/llvm/Analysis/TargetFolder.h
+++ b/llvm/include/llvm/Analysis/TargetFolder.h
@@ -189,10 +189,19 @@ class LLVM_ABI TargetFolder final : public IRBuilderFolder {
   }
 
   Value *FoldBitInsert(Value *Base, Value *Val, Value *Offset) const override {
+    auto *CBase = dyn_cast<Constant>(Base);
+    auto *CVal = dyn_cast<Constant>(Val);
+    auto *COffset = dyn_cast<Constant>(Offset);
+    if (CBase && CVal && COffset)
+      return ConstantFoldBitInsertOperands(CBase, CVal, COffset, DL);
     return nullptr;
   }
 
   Value *FoldBitExtract(Type *Ty, Value *Src, Value *Offset) const override {
+    auto *CSrc = dyn_cast<Constant>(Src);
+    auto *COffset = dyn_cast<Constant>(Offset);
+    if (CSrc && COffset)
+      return ConstantFoldBitExtractOperands(Ty, CSrc, COffset, DL);
     return nullptr;
   }
 

diff  --git a/llvm/include/llvm/IR/ConstantFolder.h b/llvm/include/llvm/IR/ConstantFolder.h
index 62b1f3fa2debd..c40db630cb960 100644
--- a/llvm/include/llvm/IR/ConstantFolder.h
+++ b/llvm/include/llvm/IR/ConstantFolder.h
@@ -175,12 +175,12 @@ class LLVM_ABI ConstantFolder final : public IRBuilderFolder {
   }
 
   Value *FoldBitInsert(Value *Base, Value *Val, Value *Offset) const override {
-    // TODO
+    // Use TargetFolder instead.
     return nullptr;
   }
 
   Value *FoldBitExtract(Type *Ty, Value *Src, Value *Offset) const override {
-    // TODO
+    // Use TargetFolder instead.
     return nullptr;
   }
 

diff  --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index bc07492569b05..442555c431d47 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -1211,6 +1211,11 @@ Constant *ConstantFoldInstOperandsImpl(const Value *InstOrCE, unsigned Opcode,
   case Instruction::ShuffleVector:
     return ConstantExpr::getShuffleVector(
         Ops[0], Ops[1], cast<ShuffleVectorInst>(InstOrCE)->getShuffleMask());
+  case Instruction::BitInsert:
+    return ConstantFoldBitInsertOperands(Ops[0], Ops[1], Ops[2], DL);
+  case Instruction::BitExtract:
+    return ConstantFoldBitExtractOperands(InstOrCE->getType(), Ops[0], Ops[1],
+                                          DL);
   case Instruction::Load: {
     const auto *LI = dyn_cast<LoadInst>(InstOrCE);
     if (LI->isVolatile())
@@ -1730,6 +1735,87 @@ Constant *llvm::ConstantFoldIntegerCast(Constant *C, Type *DestTy,
   return ConstantFoldCastOperand(Instruction::ZExt, C, DestTy, DL);
 }
 
+Constant *llvm::ConstantFoldBitInsertOperands(Constant *Base, Constant *Val,
+                                              Constant *Offset,
+                                              const DataLayout &DL) {
+  // bitinsert C, C, undef -> poison
+  if (isa<UndefValue>(Offset))
+    return PoisonValue::get(Base->getType());
+
+  // bitinsert poison, poison, C -> poison
+  if (isa<PoisonValue>(Base) && isa<PoisonValue>(Val))
+    return Base;
+
+  auto *COffset = dyn_cast<ConstantInt>(Offset);
+  if (!COffset)
+    return nullptr;
+
+  // bitinsert C, C, out_of_range -> poison
+  unsigned BaseBits = DL.getTypeSizeInBits(Base->getType());
+  unsigned Bits = DL.getTypeSizeInBits(Val->getType());
+  uint64_t Off = COffset->getZExtValue();
+  if (Off + Bits > BaseBits)
+    return PoisonValue::get(Base->getType());
+
+  // Overwriting every bit of the base is a bitcast of the value.
+  if (Bits == BaseBits)
+    return ConstantFoldCastOperand(Instruction::BitCast, Val, Base->getType(),
+                                   DL);
+
+  // bitinsert undef, undef, C -> undef
+  // Any poison bits are refined to undef.
+  if (isa<UndefValue>(Base) && isa<UndefValue>(Val))
+    return UndefValue::get(Base->getType());
+
+  // A byte constant can't mix poison or undef bits with other bits.
+  auto *CB = dyn_cast<ConstantByte>(Base);
+  // The value bits are unknown.
+  if (!CB || isa<ConstantExpr>(Val) || Val->getType()->isPointerTy())
+    return nullptr;
+
+  auto *CI = dyn_cast_or_null<ConstantInt>(
+      ConstantFoldCastOperand(Instruction::BitCast, Val,
+                              IntegerType::get(Base->getContext(), Bits), DL));
+  if (!CI)
+    return nullptr;
+
+  APInt Res = CB->getValue();
+  Res.insertBits(CI->getValue(), Off);
+  return ConstantByte::get(Base->getType(), Res);
+}
+
+Constant *llvm::ConstantFoldBitExtractOperands(Type *Ty, Constant *Src,
+                                               Constant *Offset,
+                                               const DataLayout &DL) {
+  // bitextract poison, C -> poison
+  // bitextract C, undef -> poison
+  if (isa<PoisonValue>(Src) || isa<UndefValue>(Offset))
+    return PoisonValue::get(Ty);
+
+  auto *COffset = dyn_cast<ConstantInt>(Offset);
+  if (!COffset)
+    return nullptr;
+
+  // bitextract C, out_of_range -> poison
+  unsigned Bits = DL.getTypeSizeInBits(Ty);
+  uint64_t Off = COffset->getZExtValue();
+  if (Off + Bits > DL.getTypeSizeInBits(Src->getType()))
+    return PoisonValue::get(Ty);
+
+  // bitextract undef, C -> undef
+  if (isa<UndefValue>(Src))
+    return UndefValue::get(Ty);
+
+  auto *CB = dyn_cast<ConstantByte>(Src);
+  // An integer can't be bitcast to a pointer.
+  if (!CB || Ty->isPointerTy())
+    return nullptr;
+
+  APInt Res = CB->getValue().extractBits(Bits, Off);
+  return ConstantFoldCastOperand(
+      Instruction::BitCast, ConstantInt::get(Src->getContext(), Res), Ty, DL);
+}
+
 //===----------------------------------------------------------------------===//
 //  Constant Folding for Calls
 //

diff  --git a/llvm/test/Transforms/InstSimplify/ConstProp/bitinsert-bitextract.ll b/llvm/test/Transforms/InstSimplify/ConstProp/bitinsert-bitextract.ll
new file mode 100644
index 0000000000000..1fc1c3a76c2a6
--- /dev/null
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/bitinsert-bitextract.ll
@@ -0,0 +1,378 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
+
+ at g = global i32 0
+
+define i8 @bitextract_i8_offset_0() {
+; CHECK-LABEL: define i8 @bitextract_i8_offset_0() {
+; CHECK-NEXT:    ret i8 120
+;
+  %r = bitextract i8, b32 305419896, i32 0
+  ret i8 %r
+}
+
+define i8 @bitextract_i8_offset_8() {
+; CHECK-LABEL: define i8 @bitextract_i8_offset_8() {
+; CHECK-NEXT:    ret i8 86
+;
+  %r = bitextract i8, b32 305419896, i32 8
+  ret i8 %r
+}
+
+define i8 @bitextract_i8_top_bits() {
+; CHECK-LABEL: define i8 @bitextract_i8_top_bits() {
+; CHECK-NEXT:    ret i8 18
+;
+  %r = bitextract i8, b32 305419896, i32 24
+  ret i8 %r
+}
+
+define i1 @bitextract_i1() {
+; CHECK-LABEL: define i1 @bitextract_i1() {
+; CHECK-NEXT:    ret i1 true
+;
+  %r = bitextract i1, b32 32, i32 5
+  ret i1 %r
+}
+
+define b16 @bitextract_b16() {
+; CHECK-LABEL: define b16 @bitextract_b16() {
+; CHECK-NEXT:    ret b16 4660
+;
+  %r = bitextract b16, b32 305419896, i32 16
+  ret b16 %r
+}
+
+define float @bitextract_float() {
+; CHECK-LABEL: define float @bitextract_float() {
+; CHECK-NEXT:    ret float 1.000000e+00
+;
+  %r = bitextract float, b64 4575657221408423936, i32 32
+  ret float %r
+}
+
+define i8 @bitextract_out_of_range() {
+; CHECK-LABEL: define i8 @bitextract_out_of_range() {
+; CHECK-NEXT:    ret i8 poison
+;
+  %r = bitextract i8, b32 305419896, i32 25
+  ret i8 %r
+}
+
+define i8 @bitextract_offset_width() {
+; CHECK-LABEL: define i8 @bitextract_offset_width() {
+; CHECK-NEXT:    ret i8 poison
+;
+  %r = bitextract i8, b32 305419896, i32 32
+  ret i8 %r
+}
+
+define i8 @bitextract_large_offset() {
+; CHECK-LABEL: define i8 @bitextract_large_offset() {
+; CHECK-NEXT:    ret i8 poison
+;
+  %r = bitextract i8, b32 305419896, i32 -1
+  ret i8 %r
+}
+
+define i8 @bitextract_poison_src() {
+; CHECK-LABEL: define i8 @bitextract_poison_src() {
+; CHECK-NEXT:    ret i8 poison
+;
+  %r = bitextract i8, b32 poison, i32 8
+  ret i8 %r
+}
+
+define i8 @bitextract_poison_offset() {
+; CHECK-LABEL: define i8 @bitextract_poison_offset() {
+; CHECK-NEXT:    ret i8 poison
+;
+  %r = bitextract i8, b32 305419896, i32 poison
+  ret i8 %r
+}
+
+define i8 @bitextract_undef_offset() {
+; CHECK-LABEL: define i8 @bitextract_undef_offset() {
+; CHECK-NEXT:    ret i8 poison
+;
+  %r = bitextract i8, b32 305419896, i32 undef
+  ret i8 %r
+}
+
+define i8 @bitextract_undef_src() {
+; CHECK-LABEL: define i8 @bitextract_undef_src() {
+; CHECK-NEXT:    ret i8 undef
+;
+  %r = bitextract i8, b32 undef, i32 8
+  ret i8 %r
+}
+
+define ptr @bitextract_poison_src_ptr() {
+; CHECK-LABEL: define ptr @bitextract_poison_src_ptr() {
+; CHECK-NEXT:    ret ptr poison
+;
+  %r = bitextract ptr, b64 poison, i32 0
+  ret ptr %r
+}
+
+; An integer can't be bitcast to a pointer.
+define ptr @neg_bitextract_ptr() {
+; CHECK-LABEL: define ptr @neg_bitextract_ptr() {
+; CHECK-NEXT:    [[R:%.*]] = bitextract ptr, b64 1234605616436508552, i32 0
+; CHECK-NEXT:    ret ptr [[R]]
+;
+  %r = bitextract ptr, b64 1234605616436508552, i32 0
+  ret ptr %r
+}
+
+; The source bits are unknown.
+define i32 @neg_bitextract_constexpr_src() {
+; CHECK-LABEL: define i32 @neg_bitextract_constexpr_src() {
+; CHECK-NEXT:    [[R:%.*]] = bitextract i32, b64 bitcast (ptr @g to b64), i32 0
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %r = bitextract i32, b64 bitcast (ptr @g to b64), i32 0
+  ret i32 %r
+}
+
+define ppc_fp128 @bitextract_ppc_fp128() {
+; CHECK-LABEL: define ppc_fp128 @bitextract_ppc_fp128() {
+; CHECK-NEXT:    ret ppc_fp128 bitcast (i128 84987514980498058623787163916674531328 to ppc_fp128)
+;
+  %r = bitextract ppc_fp128, b128 84987514980498058623787163916674531328, i32 0
+  ret ppc_fp128 %r
+}
+
+; The offset is unknown.
+define i8 @neg_bitextract_constexpr_offset() {
+; CHECK-LABEL: define i8 @neg_bitextract_constexpr_offset() {
+; CHECK-NEXT:    [[R:%.*]] = bitextract i8, b32 305419896, i32 ptrtoint (ptr @g to i32)
+; CHECK-NEXT:    ret i8 [[R]]
+;
+  %r = bitextract i8, b32 305419896, i32 ptrtoint (ptr @g to i32)
+  ret i8 %r
+}
+
+define b32 @bitinsert_i8() {
+; CHECK-LABEL: define b32 @bitinsert_i8() {
+; CHECK-NEXT:    ret b32 305441656
+;
+  %r = bitinsert b32 305419896, i8 -85, i32 8
+  ret b32 %r
+}
+
+define b32 @bitinsert_i1() {
+; CHECK-LABEL: define b32 @bitinsert_i1() {
+; CHECK-NEXT:    ret b32 305420024
+;
+  %r = bitinsert b32 305419896, i1 true, i32 7
+  ret b32 %r
+}
+
+define b32 @bitinsert_b8_top_bits() {
+; CHECK-LABEL: define b32 @bitinsert_b8_top_bits() {
+; CHECK-NEXT:    ret b32 -1422633352
+;
+  %r = bitinsert b32 305419896, b8 -85, i32 24
+  ret b32 %r
+}
+
+define b32 @bitinsert_half() {
+; CHECK-LABEL: define b32 @bitinsert_half() {
+; CHECK-NEXT:    ret b32 1006655096
+;
+  %r = bitinsert b32 305419896, half 1.0, i32 16
+  ret b32 %r
+}
+
+define b32 @bitinsert_out_of_range() {
+; CHECK-LABEL: define b32 @bitinsert_out_of_range() {
+; CHECK-NEXT:    ret b32 poison
+;
+  %r = bitinsert b32 305419896, i8 -85, i32 25
+  ret b32 %r
+}
+
+define b32 @bitinsert_large_offset() {
+; CHECK-LABEL: define b32 @bitinsert_large_offset() {
+; CHECK-NEXT:    ret b32 poison
+;
+  %r = bitinsert b32 305419896, i8 -85, i32 -1
+  ret b32 %r
+}
+
+define b32 @bitinsert_poison_offset() {
+; CHECK-LABEL: define b32 @bitinsert_poison_offset() {
+; CHECK-NEXT:    ret b32 poison
+;
+  %r = bitinsert b32 305419896, i8 -85, i32 poison
+  ret b32 %r
+}
+
+define b32 @bitinsert_undef_offset() {
+; CHECK-LABEL: define b32 @bitinsert_undef_offset() {
+; CHECK-NEXT:    ret b32 poison
+;
+  %r = bitinsert b32 305419896, i8 -85, i32 undef
+  ret b32 %r
+}
+
+define b64 @bitinsert_full_width_i64() {
+; CHECK-LABEL: define b64 @bitinsert_full_width_i64() {
+; CHECK-NEXT:    ret b64 1234605616436508552
+;
+  %r = bitinsert b64 bitcast (ptr @g to b64), i64 1234605616436508552, i32 0
+  ret b64 %r
+}
+
+define b64 @bitinsert_full_width_ptr() {
+; CHECK-LABEL: define b64 @bitinsert_full_width_ptr() {
+; CHECK-NEXT:    ret b64 bitcast (ptr @g to b64)
+;
+  %r = bitinsert b64 0, ptr @g, i32 0
+  ret b64 %r
+}
+
+define b32 @bitinsert_full_width_float() {
+; CHECK-LABEL: define b32 @bitinsert_full_width_float() {
+; CHECK-NEXT:    ret b32 1065353216
+;
+  %r = bitinsert b32 305419896, float 1.0, i32 0
+  ret b32 %r
+}
+
+define b32 @bitinsert_full_width_poison() {
+; CHECK-LABEL: define b32 @bitinsert_full_width_poison() {
+; CHECK-NEXT:    ret b32 poison
+;
+  %r = bitinsert b32 305419896, i32 poison, i32 0
+  ret b32 %r
+}
+
+define b32 @bitinsert_full_width_undef() {
+; CHECK-LABEL: define b32 @bitinsert_full_width_undef() {
+; CHECK-NEXT:    ret b32 undef
+;
+  %r = bitinsert b32 305419896, i32 undef, i32 0
+  ret b32 %r
+}
+
+define b128 @bitinsert_full_width_ppc_fp128() {
+; CHECK-LABEL: define b128 @bitinsert_full_width_ppc_fp128() {
+; CHECK-NEXT:    ret b128 bitcast (ppc_fp128 1.000000e+00 to b128)
+;
+  %r = bitinsert b128 0, ppc_fp128 0xM3FF00000000000000000000000000000, i32 0
+  ret b128 %r
+}
+
+define b32 @bitinsert_full_width_constexpr_val() {
+; CHECK-LABEL: define b32 @bitinsert_full_width_constexpr_val() {
+; CHECK-NEXT:    ret b32 bitcast (i32 ptrtoint (ptr @g to i32) to b32)
+;
+  %r = bitinsert b32 305419896, i32 ptrtoint (ptr @g to i32), i32 0
+  ret b32 %r
+}
+
+define b32 @bitinsert_poison_poison() {
+; CHECK-LABEL: define b32 @bitinsert_poison_poison() {
+; CHECK-NEXT:    ret b32 poison
+;
+  %r = bitinsert b32 poison, i8 poison, i32 8
+  ret b32 %r
+}
+
+define b32 @bitinsert_undef_undef() {
+; CHECK-LABEL: define b32 @bitinsert_undef_undef() {
+; CHECK-NEXT:    ret b32 undef
+;
+  %r = bitinsert b32 undef, i8 undef, i32 8
+  ret b32 %r
+}
+
+; The result would have both poison and non-poison bits.
+define b32 @neg_bitinsert_poison_val() {
+; CHECK-LABEL: define b32 @neg_bitinsert_poison_val() {
+; CHECK-NEXT:    [[R:%.*]] = bitinsert b32 305419896, i8 poison, i32 8
+; CHECK-NEXT:    ret b32 [[R]]
+;
+  %r = bitinsert b32 305419896, i8 poison, i32 8
+  ret b32 %r
+}
+
+; The result would have both undef and defined bits.
+define b32 @neg_bitinsert_undef_val() {
+; CHECK-LABEL: define b32 @neg_bitinsert_undef_val() {
+; CHECK-NEXT:    [[R:%.*]] = bitinsert b32 305419896, i8 undef, i32 8
+; CHECK-NEXT:    ret b32 [[R]]
+;
+  %r = bitinsert b32 305419896, i8 undef, i32 8
+  ret b32 %r
+}
+
+; The result would have both poison and non-poison bits.
+define b32 @neg_bitinsert_poison_base() {
+; CHECK-LABEL: define b32 @neg_bitinsert_poison_base() {
+; CHECK-NEXT:    [[R:%.*]] = bitinsert b32 poison, b8 -85, i32 8
+; CHECK-NEXT:    ret b32 [[R]]
+;
+  %r = bitinsert b32 poison, b8 -85, i32 8
+  ret b32 %r
+}
+
+define b32 @bitinsert_undef_base_poison_val() {
+; CHECK-LABEL: define b32 @bitinsert_undef_base_poison_val() {
+; CHECK-NEXT:    ret b32 undef
+;
+  %r = bitinsert b32 undef, i8 poison, i32 8
+  ret b32 %r
+}
+
+; The value bits are unknown.
+define b128 @neg_bitinsert_ptr() {
+; CHECK-LABEL: define b128 @neg_bitinsert_ptr() {
+; CHECK-NEXT:    [[R:%.*]] = bitinsert b128 0, ptr null, i32 0
+; CHECK-NEXT:    ret b128 [[R]]
+;
+  %r = bitinsert b128 0, ptr null, i32 0
+  ret b128 %r
+}
+
+; The base bits are unknown.
+define b64 @neg_bitinsert_constexpr_base() {
+; CHECK-LABEL: define b64 @neg_bitinsert_constexpr_base() {
+; CHECK-NEXT:    [[R:%.*]] = bitinsert b64 bitcast (ptr @g to b64), i8 -85, i32 8
+; CHECK-NEXT:    ret b64 [[R]]
+;
+  %r = bitinsert b64 bitcast (ptr @g to b64), i8 -85, i32 8
+  ret b64 %r
+}
+
+; The value bits are unknown.
+define b64 @neg_bitinsert_constexpr_val() {
+; CHECK-LABEL: define b64 @neg_bitinsert_constexpr_val() {
+; CHECK-NEXT:    [[R:%.*]] = bitinsert b64 0, i32 ptrtoint (ptr @g to i32), i32 8
+; CHECK-NEXT:    ret b64 [[R]]
+;
+  %r = bitinsert b64 0, i32 ptrtoint (ptr @g to i32), i32 8
+  ret b64 %r
+}
+
+; The value bits are unknown.
+define b128 @neg_bitinsert_constexpr_byte_val() {
+; CHECK-LABEL: define b128 @neg_bitinsert_constexpr_byte_val() {
+; CHECK-NEXT:    [[R:%.*]] = bitinsert b128 0, b64 bitcast (ptr @g to b64), i32 0
+; CHECK-NEXT:    ret b128 [[R]]
+;
+  %r = bitinsert b128 0, b64 bitcast (ptr @g to b64), i32 0
+  ret b128 %r
+}
+
+; The bits of a ppc_fp128 depend on endianness.
+define b256 @neg_bitinsert_ppc_fp128() {
+; CHECK-LABEL: define b256 @neg_bitinsert_ppc_fp128() {
+; CHECK-NEXT:    [[R:%.*]] = bitinsert b256 0, ppc_fp128 1.000000e+00, i32 0
+; CHECK-NEXT:    ret b256 [[R]]
+;
+  %r = bitinsert b256 0, ppc_fp128 0xM3FF00000000000000000000000000000, i32 0
+  ret b256 %r
+}


        


More information about the llvm-commits mailing list