Skip to content
3 changes: 2 additions & 1 deletion llvm/include/llvm/IR/Instructions.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,8 @@ class LoadInst : public UnaryInstruction {

/// Returns false if this type would be invalid in the
/// creation of a load atomic instruction.
static bool isValidAtomicTy(Type *Ty);
static bool isValidAtomicTy(Type *Ty, const DataLayout *DL = nullptr,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DataLayout must be mandatory

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then we need to omit it entirely because otherwise we will be checking the type size of the alloca, which we want to avoid if to optimize basictest.ll.

AtomicOrdering AO = AtomicOrdering::NotAtomic);

Value *getPointerOperand() { return getOperand(0); }
const Value *getPointerOperand() const { return getOperand(0); }
Expand Down
10 changes: 9 additions & 1 deletion llvm/lib/IR/Instructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1247,9 +1247,17 @@ void LoadInst::AssertOK() {
"Ptr must have pointer type.");
}

bool LoadInst::isValidAtomicTy(Type *Ty) {
bool LoadInst::isValidAtomicTy(Type *Ty, const DataLayout *DL,
AtomicOrdering AO) {
// TODO: Share methods with IR/Verifier.
if (!Ty->isIntOrPtrTy() && !Ty->isFloatingPointTy())
return false;
if (AO == AtomicOrdering::Release || AO == AtomicOrdering::AcquireRelease)
return false;
if (DL) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mandatory

unsigned Size = DL->getTypeSizeInBits(Ty);
return Size >= 8 && !(Size & (Size - 1));
}
return true;
}

Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Transforms/Scalar/SROA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2854,7 +2854,8 @@ class AllocaSliceRewriter : public InstVisitor<AllocaSliceRewriter, bool> {
bool visitLoadInst(LoadInst &LI) {
LLVM_DEBUG(dbgs() << " original: " << LI << "\n");

// load atomic vector would be generated, which is illegal
// Load atomic vector would be generated, which is illegal.
// TODO: Generate a generic bitcast in machine codegen instead.
if (LI.isAtomic() && !LoadInst::isValidAtomicTy(NewAI.getAllocatedType()))
return false;

Expand Down
17 changes: 17 additions & 0 deletions llvm/test/Transforms/SROA/atomic-vector.ll
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,20 @@ define ptr @atomic_vector_ptr() {
%ret = load atomic volatile ptr, ptr %indirect acquire, align 4
ret ptr %ret
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test a <2 x i16> or some other real vector. 1 x is a degenerate case


define i32 @atomic_2vector_int() {
; CHECK-LABEL: define i32 @atomic_2vector_int() {
; CHECK-NEXT: [[VAL_SROA_0:%.*]] = alloca i32, align 8
; CHECK-NEXT: store i32 undef, ptr [[VAL_SROA_0]], align 8
; CHECK-NEXT: [[VAL_SROA_0_0_VAL_SROA_0_0_RET:%.*]] = load atomic volatile i32, ptr [[VAL_SROA_0]] acquire, align 4
; CHECK-NEXT: ret i32 [[VAL_SROA_0_0_VAL_SROA_0_0_RET]]
;
%src = alloca <2 x i32>
%val = alloca <2 x i32>
%direct = alloca ptr
call void @llvm.memcpy.p0.p0.i64(ptr %val, ptr %src, i64 4, i1 false)
store ptr %val, ptr %direct
%indirect = load ptr, ptr %direct
%ret = load atomic volatile i32, ptr %indirect acquire, align 4
ret i32 %ret
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add test for the non-byte illegal case?

Loading