[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