diff --git a/llvm/lib/Target/VE/VEMCInstLower.cpp b/llvm/lib/Target/VE/VEMCInstLower.cpp --- a/llvm/lib/Target/VE/VEMCInstLower.cpp +++ b/llvm/lib/Target/VE/VEMCInstLower.cpp @@ -30,9 +30,14 @@ const MCSymbol *Symbol, AsmPrinter &AP) { VEMCExpr::VariantKind Kind = (VEMCExpr::VariantKind)MO.getTargetFlags(); - const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Symbol, AP.OutContext); - const VEMCExpr *expr = VEMCExpr::create(Kind, MCSym, AP.OutContext); - return MCOperand::createExpr(expr); + const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, AP.OutContext); + // Add offset iff MO is not jump table info or machine basic block. + if (!MO.isJTI() && !MO.isMBB() && MO.getOffset()) + Expr = MCBinaryExpr::createAdd( + Expr, MCConstantExpr::create(MO.getOffset(), AP.OutContext), + AP.OutContext); + Expr = VEMCExpr::create(Kind, Expr, AP.OutContext); + return MCOperand::createExpr(Expr); } static MCOperand LowerOperand(const MachineInstr *MI, const MachineOperand &MO, diff --git a/llvm/test/CodeGen/VE/load_off.ll b/llvm/test/CodeGen/VE/load_off.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/VE/load_off.ll @@ -0,0 +1,204 @@ +; RUN: llc < %s -mtriple=ve-unknown-unknown | FileCheck %s + +@bufi8 = global [3 x i8] zeroinitializer, align 1 +@bufi16 = global [3 x i16] zeroinitializer, align 2 +@bufi32 = global [3 x i32] zeroinitializer, align 4 +@bufi64 = global [3 x i64] zeroinitializer, align 8 +@bufi128 = global [3 x i128] zeroinitializer, align 16 +@buff32 = global [3 x float] zeroinitializer, align 4 +@buff64 = global [3 x double] zeroinitializer, align 8 +@buff128 = global [3 x fp128] zeroinitializer, align 16 + +; Function Attrs: noinline nounwind optnone +define signext i8 @loadi8s() { +; CHECK-LABEL: loadi8s: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: lea %s0, bufi8+2@lo +; CHECK-NEXT: and %s0, %s0, (32)0 +; CHECK-NEXT: lea.sl %s0, bufi8+2@hi(, %s0) +; CHECK-NEXT: ld1b.sx %s0, (, %s0) +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %0 = load i8, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @bufi8, i64 0, i64 2), align 1 + ret i8 %0 +} + +; Function Attrs: noinline nounwind optnone +define signext i16 @loadi16s() { +; CHECK-LABEL: loadi16s: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: lea %s0, bufi16+4@lo +; CHECK-NEXT: and %s0, %s0, (32)0 +; CHECK-NEXT: lea.sl %s0, bufi16+4@hi(, %s0) +; CHECK-NEXT: ld2b.sx %s0, (, %s0) +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %0 = load i16, i16* getelementptr inbounds ([3 x i16], [3 x i16]* @bufi16, i64 0, i64 2), align 2 + ret i16 %0 +} + +; Function Attrs: noinline nounwind optnone +define signext i32 @loadi32s() { +; CHECK-LABEL: loadi32s: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: lea %s0, bufi32+8@lo +; CHECK-NEXT: and %s0, %s0, (32)0 +; CHECK-NEXT: lea.sl %s0, bufi32+8@hi(, %s0) +; CHECK-NEXT: ldl.sx %s0, (, %s0) +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %0 = load i32, i32* getelementptr inbounds ([3 x i32], [3 x i32]* @bufi32, i64 0, i64 2), align 4 + ret i32 %0 +} + +; Function Attrs: noinline nounwind optnone +define i64 @loadi64s() { +; CHECK-LABEL: loadi64s: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: lea %s0, bufi64+16@lo +; CHECK-NEXT: and %s0, %s0, (32)0 +; CHECK-NEXT: lea.sl %s0, bufi64+16@hi(, %s0) +; CHECK-NEXT: ld %s0, (, %s0) +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %0 = load i64, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @bufi64, i64 0, i64 2), align 8 + ret i64 %0 +} + +; Function Attrs: noinline nounwind optnone +define i128 @loadi128s() { +; CHECK-LABEL: loadi128s: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: lea %s0, bufi128+32@lo +; CHECK-NEXT: and %s0, %s0, (32)0 +; CHECK-NEXT: lea.sl %s0, bufi128+32@hi(, %s0) +; CHECK-NEXT: ld %s0, (, %s0) +; CHECK-NEXT: lea %s1, bufi128+40@lo +; CHECK-NEXT: and %s1, %s1, (32)0 +; CHECK-NEXT: lea.sl %s1, bufi128+40@hi(, %s1) +; CHECK-NEXT: ld %s1, (, %s1) +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %0 = load i128, i128* getelementptr inbounds ([3 x i128], [3 x i128]* @bufi128, i64 0, i64 2), align 16 + ret i128 %0 +} + +; Function Attrs: noinline nounwind optnone +define zeroext i8 @loadi8z() { +; CHECK-LABEL: loadi8z: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: lea %s0, bufi8+2@lo +; CHECK-NEXT: and %s0, %s0, (32)0 +; CHECK-NEXT: lea.sl %s0, bufi8+2@hi(, %s0) +; CHECK-NEXT: ld1b.zx %s0, (, %s0) +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %0 = load i8, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @bufi8, i64 0, i64 2), align 1 + ret i8 %0 +} + +; Function Attrs: noinline nounwind optnone +define zeroext i16 @loadi16z() { +; CHECK-LABEL: loadi16z: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: lea %s0, bufi16+4@lo +; CHECK-NEXT: and %s0, %s0, (32)0 +; CHECK-NEXT: lea.sl %s0, bufi16+4@hi(, %s0) +; CHECK-NEXT: ld2b.zx %s0, (, %s0) +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %0 = load i16, i16* getelementptr inbounds ([3 x i16], [3 x i16]* @bufi16, i64 0, i64 2), align 2 + ret i16 %0 +} + +; Function Attrs: noinline nounwind optnone +define zeroext i32 @loadi32z() { +; CHECK-LABEL: loadi32z: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: lea %s0, bufi32+8@lo +; CHECK-NEXT: and %s0, %s0, (32)0 +; CHECK-NEXT: lea.sl %s0, bufi32+8@hi(, %s0) +; CHECK-NEXT: ldl.sx %s0, (, %s0) +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %0 = load i32, i32* getelementptr inbounds ([3 x i32], [3 x i32]* @bufi32, i64 0, i64 2), align 4 + ret i32 %0 +} + +; Function Attrs: noinline nounwind optnone +define i64 @loadi64z() { +; CHECK-LABEL: loadi64z: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: lea %s0, bufi64+16@lo +; CHECK-NEXT: and %s0, %s0, (32)0 +; CHECK-NEXT: lea.sl %s0, bufi64+16@hi(, %s0) +; CHECK-NEXT: ld %s0, (, %s0) +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %0 = load i64, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @bufi64, i64 0, i64 2), align 8 + ret i64 %0 +} + +; Function Attrs: noinline nounwind optnone +define i128 @loadi128z() { +; CHECK-LABEL: loadi128z: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: lea %s0, bufi128+32@lo +; CHECK-NEXT: and %s0, %s0, (32)0 +; CHECK-NEXT: lea.sl %s0, bufi128+32@hi(, %s0) +; CHECK-NEXT: ld %s0, (, %s0) +; CHECK-NEXT: lea %s1, bufi128+40@lo +; CHECK-NEXT: and %s1, %s1, (32)0 +; CHECK-NEXT: lea.sl %s1, bufi128+40@hi(, %s1) +; CHECK-NEXT: ld %s1, (, %s1) +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %0 = load i128, i128* getelementptr inbounds ([3 x i128], [3 x i128]* @bufi128, i64 0, i64 2), align 16 + ret i128 %0 +} + +; Function Attrs: noinline nounwind optnone +define float @loadf32() { +; CHECK-LABEL: loadf32: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: lea %s0, buff32+8@lo +; CHECK-NEXT: and %s0, %s0, (32)0 +; CHECK-NEXT: lea.sl %s0, buff32+8@hi(, %s0) +; CHECK-NEXT: ldu %s0, (, %s0) +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %0 = load float, float* getelementptr inbounds ([3 x float], [3 x float]* @buff32, i64 0, i64 2), align 4 + ret float %0 +} + +; Function Attrs: noinline nounwind optnone +define double @loadf64() { +; CHECK-LABEL: loadf64: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: lea %s0, buff64+16@lo +; CHECK-NEXT: and %s0, %s0, (32)0 +; CHECK-NEXT: lea.sl %s0, buff64+16@hi(, %s0) +; CHECK-NEXT: ld %s0, (, %s0) +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %0 = load double, double* getelementptr inbounds ([3 x double], [3 x double]* @buff64, i64 0, i64 2), align 8 + ret double %0 +} + +; Function Attrs: noinline nounwind optnone +define fp128 @loadf128() { +; CHECK-LABEL: loadf128: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: lea %s0, buff128+32@lo +; CHECK-NEXT: and %s0, %s0, (32)0 +; CHECK-NEXT: lea.sl %s0, buff128+32@hi(, %s0) +; CHECK-NEXT: ld %s0, (, %s0) +; CHECK-NEXT: lea %s1, buff128+40@lo +; CHECK-NEXT: and %s1, %s1, (32)0 +; CHECK-NEXT: lea.sl %s1, buff128+40@hi(, %s1) +; CHECK-NEXT: ld %s1, (, %s1) +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %0 = load fp128, fp128* getelementptr inbounds ([3 x fp128], [3 x fp128]* @buff128, i64 0, i64 2), align 16 + ret fp128 %0 +}