llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29k stars 11.95k forks source link

CellSPU assert Op.getValueType() != MVT::Other && Op.getValueType() != MVT::Flag && "Chain and flag operands should occur at end of operand list!" #3429

Closed llvmbot closed 6 years ago

llvmbot commented 16 years ago
Bugzilla Link 3057
Resolution FIXED
Resolved on Nov 07, 2018 00:22
Version trunk
OS Windows XP
Reporter LLVM Bugzilla Contributor

Extended Description

Given the following C-language code:

typedef float float4 attribute((ext_vector_type(4)));

void check(float4 *a) { a[0] = 1.0f; }

Which produces the following LLVM IR (after optimization):

; ModuleID = 'test-float4' target datalayout = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128" target triple = "ppc-unknown-linux-gnu"

define void @​check(<4 x float> %a) nounwind { entry: store <4 x float> < float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00 >, <4 x float> %a ret void }

Results in the CellSPU getting the following assertion failure:

llc: ScheduleDAGEmit.cpp:315: void llvm::ScheduleDAG::AddOperand(llvm::MachineInstr, llvm::SDValue, unsigned int, const llvm::TargetInstrDesc, llvm::DenseMap<llvm::SDValue, unsigned int, llvm::DenseMapInfo, llvm::DenseMapInfo >&): Assertion `Op.getValueType() != MVT::Other && Op.getValueType() != MVT::Flag && "Chain and flag operands should occur at end of operand list!"' failed.

Note: changing the C-language code to:

typedef float float4 attribute((ext_vector_type(4)));

void check(float4 *a) { a[1] = 1.0f; }

Which produces LLVM IR

; ModuleID = 'test-float4' target datalayout = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128" target triple = "ppc-unknown-linux-gnu"

define void @​check(<4 x float> %a) nounwind { entry: %0 = getelementptr <4 x float> %a, i32 1 ; <<4 x float>> [#uses=1] store <4 x float> < float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00 >, <4 x float> %0 make: [test-float4.o] Error 1 (ignored) ret void }

DOES NOT produce the assertion failure. So it this an optimizer bug since it looks like the getelementptr has been eliminated?

llvmbot commented 15 years ago

Verified that the assertion failure is no longer occurring.

llvmbot commented 15 years ago

I've never seen machine instructions end up in the selected selection DAG (note, I've changed "check" to "store_v4f32"):

=== store_v4f32 Initial selection DAG: SelectionDAG has 10 nodes: 0xce05840: ch = EntryToken 0xce05840: 0xe0071a4: i32 = Register #​1024 0xe00722c: i32,ch = CopyFromReg 0xce05840, 0xe0071a4 0xce05840: 0xe0072b4: i32,ch = merge_values 0xe00722c, 0xce05840 0xe00700c: f32 = ConstantFP <1.000000e+00> 0xe00711c: i32 = Constant <0> 0xe0072b4: 0xe00700c: 0xe00700c: 0xe00700c: 0xe00700c: 0xe007094: v4f32 = BUILD_VECTOR 0xe00700c, 0xe00700c, 0xe00700c, 0xe00700c 0xe0072b4: 0xe00733c: i32 = undef 0xe0073c4: ch = store 0xe0072b4:1, 0xe007094, 0xe0072b4, 0xe00733c <0xce03090:0> alignment=16 0xe00744c: ch = ret 0xe0073c4

Optimized lowered selection DAG: SelectionDAG has 8 nodes: 0xce05840: ch = EntryToken 0xe00700c: f32 = ConstantFP <1.000000e+00> 0xce05840: 0xe00700c: 0xe00700c: 0xe00700c: 0xe00700c: 0xe007094: v4f32 = BUILD_VECTOR 0xe00700c, 0xe00700c, 0xe00700c, 0xe00700c 0xce05840: 0xe0071a4: i32 = Register #​1024 0xe00722c: i32,ch = CopyFromReg 0xce05840, 0xe0071a4 0xe00733c: i32 = undef 0xe0073c4: ch = store 0xce05840, 0xe007094, 0xe00722c, 0xe00733c <0xce03090:0> alignment=16 0xe00744c: ch = ret 0xe0073c4

Legally typed node: 0xe00733c: i32 = undef Legally typed node: 0xe00700c: f32 = ConstantFP <1.000000e+00> Legally typed node: 0xe007094: v4f32 = BUILD_VECTOR 0xe00700c, 0xe00700c, 0xe00700c, 0xe00700c Legally typed node: 0xe0071a4: i32 = Register #​1024 Legally typed node: 0xce05840: ch = EntryToken Legally typed node: 0xe00722c: i32,ch = CopyFromReg 0xce05840, 0xe0071a4 Legally typed node: 0xe0073c4: ch = store 0xce05840, 0xe007094, 0xe00722c, 0xe00733c <0xce03090:0> alignment=16 Legally typed node: 0xe00744c: ch = ret 0xe0073c4 Legally typed node: 0xbfffefcc: ch = handlenode 0xe00744c Type-legalized selection DAG: SelectionDAG has 8 nodes: 0xce05840: ch = EntryToken 0xe00700c: f32 = ConstantFP <1.000000e+00> 0xce05840: 0xe00700c: 0xe00700c: 0xe00700c: 0xe00700c: 0xe007094: v4f32 = BUILD_VECTOR 0xe00700c, 0xe00700c, 0xe00700c, 0xe00700c 0xce05840: 0xe0071a4: i32 = Register #​1024 0xe00722c: i32,ch = CopyFromReg 0xce05840, 0xe0071a4 0xe00733c: i32 = undef 0xe0073c4: ch = store 0xce05840, 0xe007094, 0xe00722c, 0xe00733c <0xce03090:0> alignment=16 0xe00744c: ch = ret 0xe0073c4

Legalized selection DAG: SelectionDAG has 9 nodes: 0xce05840: ch = EntryToken 0xe0072b4: i32 = Constant <1065353216> 0xce05840: 0xe0072b4: 0xe0072b4: 0xe0072b4: 0xe0072b4: 0xe00711c: v4i32 = BUILD_VECTOR 0xe0072b4, 0xe0072b4, 0xe0072b4, 0xe0072b4 0xe0074d4: v4f32 = bit_convert 0xe00711c 0xce05840: 0xe0071a4: i32 = Register #​1024 0xe00722c: i32,ch = CopyFromReg 0xce05840, 0xe0071a4 0xe00733c: i32 = undef 0xe0073c4: ch = store 0xce05840, 0xe0074d4, 0xe00722c, 0xe00733c <0xce03090:0> alignment=16 0xe00755c: ch = SPUISD::RET_FLAG 0xe0073c4

Replacing.3 0xe0073c4: ch = store 0xce05840, 0xe0074d4, 0xe00722c, 0xe00733c <0xce03090:0> alignment=16 With: 0xe00700c: ch = store 0xce05840, 0xe00711c, 0xe00722c, 0xe00733c <0xce03090:0> alignment=16 Optimized legalized selection DAG: SelectionDAG has 8 nodes: 0xce05840: ch = EntryToken 0xe0072b4: i32 = Constant <1065353216> 0xce05840: 0xe0072b4: 0xe0072b4: 0xe0072b4: 0xe0072b4: 0xe00711c: v4i32 = BUILD_VECTOR 0xe0072b4, 0xe0072b4, 0xe0072b4, 0xe0072b4 0xce05840: 0xe0071a4: i32 = Register #​1024 0xe00722c: i32,ch = CopyFromReg 0xce05840, 0xe0071a4 0xe00733c: i32 = undef 0xe00700c: ch = store 0xce05840, 0xe00711c, 0xe00722c, 0xe00733c <0xce03090:0> alignment=16 0xe00755c: ch = SPUISD::RET_FLAG 0xe00700c

entry: 0xe012ab8, LLVM BB @​0xce030d0, ID#0: Selected selection DAG: SelectionDAG has 8 nodes: 0xe00722c: i32 = TargetConstant <16256> 0xe00711c: v4i32 = ILHUv4i32 0xe00722c 0xe0073c4: i32 = TargetConstant <0> 0xe0071a4: i32 = Register #​1024 0xe007094: ch = MemOperand <0xce03090:0> 0xce05840: ch = EntryToken 0xe00700c: ch = STQXv4i32 0xe00711c, 0xe0073c4, 0xe0071a4, 0xe007094, 0xce05840 0xe00755c: ch = RET 0xe00700c

What's happening is that the addressing mode selection logic in SPUDAGToDAGISel class doesn't know about stores, can't determine that the store is really a D-Form address and defaults to a X-form address. (Note: I have no idea why this early and eager instruction selection is happening, but it's easy to work around. Also will have to check direct loads as well.)

Patch forthcoming.